molaga
molaga

Reputation: 189

in mongo, cannot perform $setIntersection on array with aggregate into project

I have this two collection which each document presents a chat session:

{
"_id" : ObjectId("58136ba83bdddd2d3cd4b3fb"),
"Created" : ISODate("2016-10-28T15:15:52.563Z"),
"Messages" : [ 
    {
        "Created" : ISODate("2016-10-28T15:15:52.567Z"),
        "ReadBy" : [ 
            ObjectId("57c96a14870ae36ede4d8085"), 
            ObjectId("57c972b6fc8effecde6cf0fa")
        ],
        "Content" : "Hello"
    }
  ]
}

{
"_id" : ObjectId("5813ac380a45415df8e7fc08"),
"Created" : ISODate("2016-10-28T15:16:52.563Z"),
"Messages" : [ 
    {
        "Created" : ISODate("2016-10-28T15:15:52.567Z"),
        "ReadBy" : [ 
            ObjectId("57c96a14870ae36ede4d8234"), 
            ObjectId("57c972b6fc8effecde6cf987")
        ],
        "Content" : "Hello2"
    }
  ]
}

I am trying to use $aggregate with $project, and to perform a simple $setIntersection in order to get matching ObjectIds.

This is the projection:

db.getCollection('Chats').aggregate([
{
    $project: {
        Created: 1,
        Messages: 1,
        Match: {
            $setIntersection: [ "$Messages.ReadBy", [ObjectId("57c96a14870ae36ede4d8085")] ]
        },
        ReadBy: "$Messages.ReadBy"
    }
  }
])

The result i am getting from this aggregate, seems to insert "$Messages.ReadBy" into Sub-Array of Array [[ObjectId("....")]] for example.

The Result is that $setIntersection returns null although there is something relevant for me, and the new "ReadBy" field i added for debug shows the problem of sub-array:

{
"_id" : ObjectId("58136ba83bdddd2d3cd4b3fb"),
"Created" : ISODate("2016-10-28T15:15:52.563Z"),
"Messages" : [ 
    {
        "Created" : ISODate("2016-10-28T15:15:52.567Z"),
        "ReadBy" : [ 
            ObjectId("57c96a14870ae36ede4d8085"), 
            ObjectId("57c972b6fc8effecde6cf0fa")
        ],
        "Content" : "Hello"
    }
],
"Match" : [],
"ReadBy" : [ 
    [ 
        ObjectId("57c96a14870ae36ede4d8085"), 
        ObjectId("57c972b6fc8effecde6cf0fa")
    ]
  ]
}

{
"_id" : ObjectId("5813ac380a45415df8e7fc08"),
"Created" : ISODate("2016-10-28T15:16:52.563Z"),
"Messages" : [ 
    {
        "Created" : ISODate("2016-10-28T15:15:52.567Z"),
        "ReadBy" : [ 
            ObjectId("57c96a14870ae36ede4d8234"), 
            ObjectId("57c972b6fc8effecde6cf987")
        ],
        "Content" : "Hello2"
    }
],
"Match" : [],
"ReadBy" : [ 
    [ 
        ObjectId("57c96a14870ae36ede4d8234"), 
        ObjectId("57c972b6fc8effecde6cf987")
    ]
  ]
}

Why is "Match" field returns empty array? And why "ReadBy" wrapping the source field with extra array?

Upvotes: 0

Views: 552

Answers (1)

felix
felix

Reputation: 9285

a solution is to use $arrayElemAt to get the sub array.

the new query is

db.getCollection('Chats').aggregate([
   {
      $project:{
         Created:1,
         Messages:1,
         Match:{
            $setIntersection:[
               {
                  $arrayElemAt:[
                     "$Messages.ReadBy",
                     0
                  ]
               },
               [
                  ObjectId("57c96a14870ae36ede4d8085")
               ]
            ]
         },
         ReadBy:"$Messages.ReadBy"
      }
   }
])

and the result is now

{
    "_id" : ObjectId("58136ba83bdddd2d3cd4b3fb"),
    "Created" : ISODate("2016-10-28T15:15:52.563Z"),
    "Messages" : [
        {
            "Created" : ISODate("2016-10-28T15:15:52.567Z"),
            "ReadBy" : [
                ObjectId("57c96a14870ae36ede4d8085"),
                ObjectId("57c972b6fc8effecde6cf0fa")
            ],
            "Content" : "Hello"
        }
    ],
    "Match" : [
        ObjectId("57c96a14870ae36ede4d8085")
    ],
    "ReadBy" : [
        [
            ObjectId("57c96a14870ae36ede4d8085"),
            ObjectId("57c972b6fc8effecde6cf0fa")
        ]
    ]
}
{
    "_id" : ObjectId("5813ac380a45415df8e7fc08"),
    "Created" : ISODate("2016-10-28T15:16:52.563Z"),
    "Messages" : [
        {
            "Created" : ISODate("2016-10-28T15:15:52.567Z"),
            "ReadBy" : [
                ObjectId("57c96a14870ae36ede4d8234"),
                ObjectId("57c972b6fc8effecde6cf987")
            ],
            "Content" : "Hello2"
        }
    ],
    "Match" : [ ],
    "ReadBy" : [
        [
            ObjectId("57c96a14870ae36ede4d8234"),
            ObjectId("57c972b6fc8effecde6cf987")
        ]
    ]
}

Upvotes: 1

Related Questions