Mongodb使用多个过滤器聚合

javapedia.net

我正在学习Mongodb聚合函数,并且正在研究查询。我的文档如下所示。

[
    {
        "_id": 17,
        "members": [{
                "email": "[email protected]",
                "status": "pending",
                "joined": ISODate("2020-05-20T02:04:00Z")
            },
            {
                "email": "[email protected]",
                "status": "pending",
                "joined": ISODate("2020-05-20T02:36:00Z")
            }
        ],
        "messages": [{
                "c": "m1",
                "ts": ISODate("2020-05-20T02:04:15Z")
            },
            {
                "c": "m2",
                "ts": ISODate("2020-05-20T02:36:31Z")
            }
    
        ]
    }
]

每个文档都有2个数组:成员和消息。我需要过滤成员中的一个元素(使用电子邮件),并根据与“ messages.ts”属性匹配的“ members.joined”属性过滤消息。

我尝试了不同的方法,但尚未实现。在下面的查询中,我对日期ISODate(“ 2020-05-20T02:36:00Z”)进行了硬编码,而不是使用member.joined属性。如何编写优化查询以实现相同目的?

db.coll.aggregate([
  {
    $match: {
      _id: 17,
      "members.email": "[email protected]"
    }
  },
  {
    $project: {
      messages: {
        $filter: {
          input: "$messages",
          as: "messs",
          cond: {
            $gte: [
              "$$messs.ts",
              ISODate("2020-05-20T02:36:00Z") // supposed to have members.$.joined property here
            ]
          }
        }
      }
    }
  }
])

预期结果是应该打印的消息中的第二个元素。

谁-假面真灵魂

您可以尝试以下聚合查询中的任何一个:

db.collection.aggregate([
    {
      $match: { _id: 17, "members.email": "[email protected]" }
    },
    /** If you need `members` array as is i.e; unfiltered in response, So instead of expensive iteration on `members` array we can get `joined` value as like below */
    {
      $addFields: {
        messages: {
          $let: {
            vars: {
              messagesArr: {
                $reduce: {
                  input: "$messages",
                  initialValue: { data: [], joinedTime: { $arrayElemAt: [ "$members.joined", { $indexOfArray: [ "$members.email", "[email protected]" ] } ] } },
                  in: {
                    data: {
                      $cond: [ { $gte: [ "$$this.ts", "$$value.joinedTime" ] },
                               { $concatArrays: [ "$$value.data", [ "$$this" ] ] }, // If condition is met concat holding array with new object
                               "$$value.data" // If not just return the holding array, doesn't add current object to array
                      ]
                    },
                    joinedTime: "$$value.joinedTime" // maintaining joined value
                  }
                }
              }
            },
            in: "$$messagesArr.data" // return newly created array in `$reduce` using `$let`
          }
        }
      }
    }
  ])

测试: mongoplayground

参考: 聚合

因此,上面的查询将返回过滤后的messages数组和原始members数组。以防万一,如果您还需要members过滤,然后在以下$addFields阶段添加以下内容$match(我们假设这email是唯一的),这样做可以避免在大型数组上进行迭代:

{
    $addFields: {
      members: {
        $arrayElemAt: [
          "$members",
          {
            $indexOfArray: [
              "$members.email",
              "[email protected]"
            ]
          }
        ]
      }
    }
  }

当您执行上述操作时,members将是一个已过滤的对象。这样$reduce就可以了joinedTime: "$members.joined"

测试: mongoplayground

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

MongoDB 聚合过滤器

来自分类Dev

mongoDB中的多个过滤器

来自分类Dev

MongoDB聚合以使用地图,过滤器,缩小来添加字段

来自分类Dev

从多个数组返回特定值的聚合过滤器

来自分类Dev

基于最大值的MongoDB聚合过滤器

来自分类Dev

Mongodb 聚合过滤器在父属性上查找

来自分类Dev

使用熊猫应用多个过滤器

来自分类Dev

在Laravel中使用多个过滤器

来自分类Dev

使用“多个过滤器”的Angular JS

来自分类Dev

对多个过滤器使用别名

来自分类Dev

在弹性搜索中对过滤器使用聚合

来自分类Dev

使用动态过滤器聚合R Shiny中的数据

来自分类Dev

使用查询过滤器确定聚合范围

来自分类Dev

C#中的多个MongoDb过滤器

来自分类Dev

使用多个过滤器值过滤数据

来自分类Dev

灰烬过滤器-使用多个值进行过滤

来自分类Dev

使用多个过滤器过滤表行

来自分类Dev

使用多个过滤器过滤Array of Array

来自分类Dev

无法使用过滤器过滤多个字段

来自分类Dev

灰烬过滤器-使用多个值进行过滤

来自分类Dev

Lucene使用多个过滤器过滤索引文档

来自分类Dev

多个过滤器PHPExcel

来自分类Dev

ICollectionView多个过滤器

来自分类Dev

多个过滤器PHPExcel

来自分类Dev

MongoDb过滤器阵列

来自分类Dev

MongoDB查询过滤器

来自分类Dev

MongoDB:括号过滤器

来自分类Dev

SQL聚合和过滤器功能

来自分类Dev

Django Rest过滤器聚合