Bosen
Bosen

Reputation: 941

Does $setIntersection work with objects?

I cant seem to get $setIntersection to work with objects.

Example:

Object 1:

[
  {name: "test5", value:5},
  {name: "test4", value:4},
  {name: "test3", value:3},
  {name: "test2", value:2}
]

Object 2:

[
  {name: "test5", value:5},
  {name: "test422", value:422},
  {name: "test333", value:3333},
  {name: "test211", value:211}
]

$setIntersection would return me [] instead of this:

[
  {name: "test5', value:5}
]

If $setIntersection does not work with Objects, is there any work around that I can use?

Upvotes: 0

Views: 1086

Answers (2)

Dushyant Bangal
Dushyant Bangal

Reputation: 6403

You cannot compare the arrays in two different documents here. For this to work, both of these arrays need to be in same document (or supplied directly as argument instead of the field name).

$setIntersection takes two or more arrays as input. It does not compare objects in different documents, which I think is what you are doing.

The following commands worked fine for me:
Insert:

db.mycol.insert({f1:[
  {name: "test5", value:5},
  {name: "test4", value:4},
  {name: "test3", value:3},
  {name: "test2", value:2}
],f2:[
  {name: "test5", value:5},
  {name: "test422", value:422},
  {name: "test333", value:3333},
  {name: "test211", value:211}
]})

Output:
WriteResult({ "nInserted" : 1 })

Aggregate:

db.mycol.aggregate([{$project:{com:{$setIntersection:["$f1","$f2"]}}}])

Output:

{ "_id" : ObjectId("59f02eba7f11fa2e1df15e53"), "com" : [ { "name" : "test5", "value" : 5 } ] }

Upvotes: 0

Neil Lunn
Neil Lunn

Reputation: 151092

Seems you are doing it wrong:

If I insert an object with an array like so:

db.test.insert({
    "a" : [ 
        {
            "name" : "test5",
            "value" : 5.0
        }, 
        {
            "name" : "test4",
            "value" : 4.0
        }, 
        {
            "name" : "test3",
            "value" : 3.0
        }, 
        {
            "name" : "test2",
            "value" : 2.0
        }
    ]
})

And I run an .aggregate() with $setInsersection and the supplied array of objects like so:

db.getCollection('test').aggregate([
  { "$project": {
    "a": {
      "$setIntersection": [
        "$a",
        [
          {name: "test5", value: 5},
          {name: "test422", value: 422},
          {name: "test333", value: 3333},
          {name: "test211", value: 211}
        ]
      ]    
    }  
  }}
])

Then I get the expected result:

/* 1 */
{
    "_id" : ObjectId("59f02df75b9b8bb266a563cb"),
    "a" : [ 
        {
            "name" : "test5",
            "value" : 5.0
        }
    ]
}

If the properties are "reversed", as in:

db.getCollection('test').aggregate([
  { "$project": {
    "a": {
      "$setIntersection": [
        "$a",
        [
          { value: 5, name: "test5" },
          {name: "test422", value: 422},
          {name: "test333", value: 3333},
          {name: "test211", value: 211}
        ]
      ]    
    }  
  }}
])

Then the result array is "empty", as should be expected because { "name": "test5", "value": 5 } is not the same as { "value": 5, "test": name } as far as a "set" is concerned.

Upvotes: 1

Related Questions