MongoDB聚合管道和字段匹配

MongoDB aggregate pipeline and field matching

我真的需要了解我的设计是否有问题,或者我只是找不到正确的解决方案。我的 collection 中的文档如下所示:

{
  "_id" : {
    "owner" : "eight@home",
    "day" : 5.0,
    "month" : 0.0
  },
  "value" : {
    "userId" : 7.0,
    "session" : 5.0,
    "no_closed" : 1.0,
    "data" : {
      "sentMessage" : [{
          "adId" : 19.0,
          "detail" : {
            "timestamp" : 1420806952000.0
          }
        }, {
          "adId" : 19.0,
          "detail" : {
            "timestamp" : 1420806969000.0
          }
        }],
      "receivedMessage" : [{
          "adId" : 1.0,
          "detail" : {
            "timestamp" : 1420806955000.0
          }
        }]
    }
  }
}

我需要的是获取 sentMessage aapId 字段与 receivedMessage appId 匹配的所有文档。想象一下,用户使用不同的应用程序通过同一个服务器互相发送消息,我需要找到用户在特定时间段内通过同一个应用程序发送和接收的消息。

谢谢

是的,您的字段似乎被称为 "adId" 而不是您声称的 "aapId"。您也没有为正匹配提供数据样本,这并没有真正帮助。但是哦好吧...

主要使用$map and $anyElementTrue运算符遍历数组元素进行逻辑比较

不理想,因为您依赖聚合框架的投影来确定数组中的元素是否具有匹配条件。您也可以使用 $where 在 JavaScript 中对此进行编码,但由于对 JavaScript 代码和对象转换的评估,这可能会导致性能更差:

db.collection.aggregate([
    { "$project": {
         "value": 1,
         "matched": {
             "$anyElementTrue": [
                 { "$map": {
                     "input": "$value.data.sentMessage",
                     "as": "sent",
                     "in": {
                         "$anyElementTrue": [
                             { "$map": {
                                 "input": "$value.data.receivedMessage",
                                 "as": "received",
                                 "in": {
                                     "$eq": [ "$$sent.adId", "$$received.adId" ]
                                 }
                             }}
                         ]
                     }
                 }}
             ]
         }
    }},
    { "$match": { "matched": true } }
])

简单的原理。将每个数组元素与其他数组元素进行比较,并寻找至少一个匹配项的可能性。那么结果就是true,只有return满足条件的