MongoDB聚合管道和字段匹配

时间:2015-01-12 09:42:50

标签: mongodb mongodb-query aggregation-framework

我真的需要了解我是否制作了破碎的设计,或者我找不到合适的解决方案。我的收藏中的文档如下所示:

{
  "_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匹配的所有文档。想象一下,用户使用不同的应用程序通过同一台服务器互相发送消息,我需要找到用户在一段时间内通过同一个应用程序发送和接收的消息。

由于

1 个答案:

答案 0 :(得分:1)

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

主要使用$map$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并返回符合条件的那些。