在mongo中,无法对聚合到项目的数组执行$ setIntersection

时间:2016-10-28 20:16:31

标签: mongodb

我有这两个集合,每个文档都提供一个聊天会话:

{
"_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"
    }
  ]
}

我正在尝试将$ aggregate与$ project一起使用,并执行一个简单的$ setIntersection以获得匹配的ObjectIds。

这是预测:

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

我从这个聚合中获得的结果似乎是将“$ Messages.ReadBy”插入到数组[[ObjectId(“....”)]的子数组中。例如。

结果是$ setIntersection返回null虽然有一些与我相关的东西,并且为调试添加的新“ ReadBy ”字段显示了子数组的问题:

{
"_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")
    ]
  ]
}

为什么“匹配”字段返回空数组? 为什么“ReadBy”用额外的数组包装源字段?

1 个答案:

答案 0 :(得分:1)

解决方案是使用$ arrayElemAt来获取子数组。

新查询

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

现在的结果是

{
    "_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")
        ]
    ]
}