Ayush Gupta
Ayush Gupta

Reputation: 9305

Compare Properties from Array to Single Property in Document

I have a mongoDB orders collection, the documents of which look as follows:

[{
    "_id" : ObjectId("59537df80ab10c0001ba8767"),
    "shipments" : {
        "products" : [
            {
                "orderDetails" : {
                    "id" : ObjectId("59537df80ab10c0001ba8767")
                }
            },
            {
                "orderDetails" : {
                    "id" : ObjectId("59537df80ab10c0001ba8767")
                }
            }
        ]
    },
}
{
    "_id" : ObjectId("5953831367ae0c0001bc87e1"),
    "shipments" : {
        "products" : [
            {
                "orderDetails" : {
                    "id" : ObjectId("5953831367ae0c0001bc87e1")
                }
            }
        ]
    },
}]

Now, from this collection, I want to filter out the elements in which, any of the values at shipments.products.orderDetails.id path is same as value at _id path.

I tried:

db.orders.aggregate([{
    "$addFields": {
        "same": {
            "$eq": ["$shipments.products.orderDetails.id", "$_id"]
        }
    }
}])

to add a field same as a flag to decide whether the values are equal, but the value of same comes as false for all documents.

EDIT What I want to do is compare the _id field the the documents with all shipments.products.orderDetails.id values in the array. If even 1 of the shipments.products.orderDetails.ids match the value of the _id field, I want that document to be present in the final result.

PS I am using MongoDB 3.4, and have to use the aggregation pipeline.

Upvotes: 0

Views: 288

Answers (1)

Neil Lunn
Neil Lunn

Reputation: 151190

Your current attempt fails because the notation returns an "array" in comparison with a "single value".

So instead either use $in where available, which can compare to see if one value is "in" an array:

db.orders.aggregate([
  { "$addFields": {
    "same": {
      "$in": [ "$_id", "$shipments.products.orderDetails.id" ]  
    }  
  }}
])

Or notate both as arrays using $setIsSubset

db.orders.aggregate([
  { "$addFields": {
    "same": {
      "$setIsSubset": [ "$shipments.products.orderDetails.id", ["$_id"] ]  
    }  
  }}
])

Where in that case it's doing a comparison to see if the "sets" have an "intersection" that makes _id the "subset" of the array of values.

Either case will return true when "any" of the id properties within the array entries at the specified path are a match for the _id property of the document.

Upvotes: 1

Related Questions