0

I would like to know how to save a part of the document, the $lookup method return for me. Here is an example:

How do I save only the abbreviation array into eOTD_term collection?

I have two collections:

ex. doc from eOTD_abbreviation

    {
        "_id" : ObjectId("59bc32fd7d7934a6a7a47d08"),
        "abbreviationID" : "0161-1#AB-000282#1",
        "termID" : "0161-1#TM-623205#1",
        "abbreviation" : "CONSTR,LGHT"
    }

ex. doc from eOTD_term

{
    "_id" : ObjectId("59bc2d7e7d7934a6a7777540"),
    "termID" : "0161-1#TM-623205#1",
    "conceptID" : "0161-1#01-082401#1",
    "term" : "CONSTRUCT,LIGHT",
}

termID is my unique key that exist in both collections.

I have tried the following:

db.eOTD_term.aggregate([
  {
    $lookup: {
      from: "eOTD_abbreviation",
      localField: "termID",
      foreignField: "termID",
      as: "abbreviation"
    }
  },
  {
    $match: { abbreviation: { $ne: [] } }
  }
]);

And I get back (one of the docs the aggregation returns):

{emphasized text
    "_id" : ObjectId("59bc2d7e7d7934a6a7777540"),
    "termID" : "0161-1#TM-623205#1",
    "conceptID" : "0161-1#01-082401#1",
    "term" : "CONSTRUCT,LIGHT",
    "abbreviation" : [  <----------- THIS ARRAY 
        {
            "_id" : ObjectId("59bc32fd7d7934a6a7a47d08"),
            "abbreviationID" : "0161-1#AB-000282#1",
            "termID" : "0161-1#TM-623205#1",
            "abbreviation" : "CONSTR,LGHT"
        }
    ]
}
Isak La Fleur
  • 4,428
  • 7
  • 34
  • 50

1 Answers1

1

This will save the content of abbreviation array back to eOTD_term:

db.eOTD_term.insertMany(
    db.eOTD_term.aggregate([
      {
        $lookup: {
          from: "eOTD_abbreviation",
          localField: "termID",
          foreignField: "termID",
          as: "abbreviation"
        }
      },
      {
        $match: { abbreviation: { $ne: [] } }
      },
      {
        $unwind: "$abbreviation"
      },
      {
       $replaceRoot: { newRoot: "$abbreviation" }
      },
    ]).result,
    {
    ordered: false <-- prevents from failing on unique constraints
    }
)

However if the result of aggregation is big you may run out of memory.

You can also try using "$out" stage instead of insertMany: How do I append Mongo DB aggregation results to an existing collection?

  • 1
    It should be noted that simply placing `$unwind` directly following the `$lookup` makes the `$match` redundant and a lot more efficient due to [how MongoDB actually hanldes that combination internally](https://docs.mongodb.com/manual/core/aggregation-pipeline-optimization/#lookup-unwind-coalescence). Note also that `$out` would fail if the new "root" `_id` values are not unique, but would be generally preferable to feeding "all" results into `.insertMany()` without "batching" requests. – Neil Lunn Sep 18 '17 at 00:25