【问题标题】:Mongoose aggregate query to filter value from the ref collectionMongoose 聚合查询从 ref 集合中过滤值
【发布时间】:2023-03-23 19:39:01
【问题描述】:

我有 2 个收藏品如下:

事件

{
    "_id" : ObjectId("61f272dd1fac703fec69105a"),
    "eventActivity" : [  
        ObjectId("61f76703196ea94bd43fa92e"),
    ]
}

事件活动

{
    "_id" : ObjectId("61f76703196ea94bd43fa92e"),
    "activity" : ObjectId("61f2a69bfe99e07db083de50"),
}

基于上面的集合,eventeventActivity 字段,它指的是event-activity 集合。我正在尝试按event-activity.activity 的值过滤事件。

例如,如果我的过滤选择在数组['61d6b2060d6fe32d9853ad40', '61f2a69bfe99e07db083de50'] 中有活动,它将返回该事件。如果过滤选择的活动 ID 为 ['61d6b2060d6fe32d9853ad40'],则不应返回任何事件,因为 event-activity

中没有具有该活动 ID 的事件

我无法真正理解聚合查找的工作原理,但我试过了,但它不起作用。

event.aggregate([
    {"$lookup":{
        "from":"event-activity",
        "localField":"activity",
        "foreignField":"_id",
        "as":"event-activity"
     }},
     {
         "$match":{
             "event-activity.activity":{
                 "$in":["61d6b2060d6fe32d9853ad40","61f2a69bfe99e07db083de50"]
              }
          }
      }
])

我提到了manual here

或者可以由find()代替吗?

【问题讨论】:

    标签: mongodb mongoose aggregate lookup


    【解决方案1】:

    查询

    • 您可以通过管道使用查找并将匹配项放入其中
    • 如果查找结果为空,您可以根据需要删除或保留文档,如下所示 {"$match":{"$expr":{"$ne":["$activities", []]}}}

    Test code here

    event.aggregate(
    [{"$lookup":
      {"from":"event-activity",
       "localField":"eventActivity",
       "foreignField":"_id",
       "pipeline":
       [{"$match":
         {"activity":
          {"$in":
           [ObjectId("61d6b2060d6fe32d9853ad40"),
            ObjectId("61f2a69bfe99e07db083de50")]}}}],
       "as":"activities"}}])
    

    【讨论】:

    • 您好,谢谢。我会测试一下。
    • 您好,再次感谢您的代码。我对其进行了测试,如果我理解正确,第二个要删除的查询实际上只是从联接中删除查找文档,对吗?但它仍在返回事件?如果查找也是空的,我的目标是完全不返回事件。类似于 SQL 查询中的东西(不知道你是否熟悉),如果连接字段值为空,则不会返回任何内容。
    • 是的,我以为你想要这个,但我不确定,这就是为什么我说你可以使用 {"$match":{"$expr":{"$ne":["$activities", []]}}} 如果你愿意,如果查找为空,则删除偶数,你可以在之后添加这个阶段管道中的查找阶段。 {lookup ..} {match ..}试试吧我觉得你想要this
    • 啊,我明白了,我想我错误地执行了查询。现在我看到了你的第二个例子,这就是我需要的。非常感谢!
    【解决方案2】:

    如果我理解正确,您可以使用此聚合查询:

    此查询使用$lookuppipeline,其中结果由$in 匹配给出。因此,连接将返回 event-activity.activity 在数组 event.eventActivity 中的值。

    db.event.aggregate([
      {
        "$lookup": {
          "from": "event-activity",
          "as": "activities",
          "let": {
            "ea": "$eventActivity"
          },
          "pipeline": [
            {
              "$match": {
                "$expr": {
                  "$in": [
                    "$activity",
                    "$$ea"
                  ]
                }
              }
            }
          ]
        }
      }
    ])
    

    示例here 我使用整数作为activity 以更轻松地进行连接。

    【讨论】:

    • 感谢您花时间编写示例查询,但这不是我想要的。 event.eventActivity 不是指event-activity.activity。相反,event.eventActivity = event-activity._idevent-activity.activity 指的是另一个集合,但我真的不需要查找该集合。这就是为什么我没有将它包含在我的问题中。但我需要根据event-activity.activity 的值过滤事件。希望我的阐述不会让您感到困惑:)
    猜你喜欢
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-22
    • 2018-12-11
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多