Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find MongoDB documents in one collection not referenced by documents in another collection?

Tags:

mongodb

I am looking for an efficient way in MonogDB to determine, which documents in one collection are not referenced by documents in another collection.

The database comprises two collections, inventory and tags, where some (not all) documents in inventory reference one of the tags documents:

{
    "_id" : ObjectId("5e8df3c02e197074f39f61ea"), 
    "tag" : ObjectId("5e89a1af96d5d8b30aead768"), 
    "ean" : "5707196199178", 
    "location" : "shelf 1"
},
{
    "_id" : ObjectId("5e8df211727079cdc24e20e1"), 
    "ean" : "5707196199178", 
    "location" : "shelf 1"
}

The 'tags' documents are without any reference to documents in inventory:

{
    "_id" : ObjectId("5e7d174fc63ce5b0ca80b89a"), 
    "nfc" : { "id" : "04:5f:ae:f2:c2:66:81" }, 
    "barcode" : { "code" : "29300310", "type" : "EAN8" }
},
{
    "_id" : ObjectId("5e89a1af96d5d8b30aead768"), 
    "nfc" : { "id" : "04:48:af:f2:c2:66:80" }, 
    "barcode" : { "code" : "29300716", "type" : "EAN8" }
},
{
    "_id" : ObjectId("5e7d1756c63ce5b0ca80b89c"), 
    "nfc" : { "id" : "04:02:ae:f2:c2:66:81" }, 
    "barcode" : { "code" : "29300648", "type" : "EAN8" }
}

Since not all documents in tags are used in inventory documents, I cannot simply have them as sub-documents.

Now I need to determine, which of the tags documents are not referenced by any inventory document. I would prefer not to have to maintain back references from tags to inventory to not risk inconsistencies (unless this can be done automatically by MongoDB?).

I'm very new to MongoDB, and from I've learned so far I'm under the impression that a view is probably what I need. But I seem to lack the proper search terms to find examples that help me understand enough to proceed. Maybe I need something different, here I'm hoping for your input to point me in the right direction.

like image 254
Andy Avatar asked Oct 17 '25 14:10

Andy


1 Answers

You need to perform MongoDB aggregation with $lookup operator that allows two collections to be joined.

If there are "tags documents are not referenced by any inventory document", join field would be an empty array.

In the next step, we filter empty arrays with $size operator.

Try the query below:

db.tags.aggregate([
  {
    $lookup: {
      from: "inventory",
      localField: "_id",
      foreignField: "tag",
      as: "join"
    }
  },
  {
    $match: {
      "join": {
        $size: 0
      }
    }
  },
  {
    $project: {
      join: 0
    }
  }
])

tags not referenced | inventory not referenced

like image 73
Valijon Avatar answered Oct 20 '25 18:10

Valijon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!