Mongodb – NoSQL- automatically cache and update references to other documents as embedded

mongodbnosql

To avoid having to look up referenced documents, one practice is to embed them (e.g. https://docs.mongodb.com/manual/tutorial/model-embedded-one-to-many-relationships-between-documents/).

Is there a way to have those embedded documents actually be separate and be referenced yet be "automatically embedded" like by some sort of functionality which automatically stores their data in the document which is referencing them – almost like an automatic "embedding cache" of sorts.

I'm not referring to them being automatically retrieved by reference, but an actual copy being stored and updated automatically.

I know this could be built manually, but I'm wondering what may exist already which can do this, preferably something inherent to MongoDB, but it doesn't have to be.

While I'm asking this about MongoDB in particular, if someone knows of something like this for other NoSQL databases, I'd be interested to hear about that as well as an answer.

Best Answer

You may be looking for MongoDB Aggregation pipeline stage $lookup.

Example: A collection orders contains the following documents:

{ "_id" : 1, "item" : "abc", "price" : 12, "quantity" : 2 }
{ "_id" : 2, "item" : "jkl", "price" : 20, "quantity" : 1 }

Another collection inventory contains the following documents:

{ "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 }
{ "_id" : 4, "sku" : "jkl", description: "product 4", "instock" : 70 }

The following aggregation operation on the orders collection joins the documents from orders with the documents from the inventory collection

db.orders.aggregate([
    {
      $lookup:
        {
          from: "inventory",
          localField: "item",
          foreignField: "sku",
          as: "inventory_docs"
        }
   }
])

Example output:

{
  "_id" : 1,
   "item" : "abc",
  "price" : 12,
  "quantity" : 2,
  "inventory_docs" : [
    { "_id" : 1, "sku" : "abc", description: "product 1", "instock" : 120 }
  ]
}

See more examples.

You could combine $lookup with $out stage to create another collection. See related $graphLookup