【问题标题】:MongoDB $lookup on one document's array of objectMongoDB $查找一个文档的对象数组
【发布时间】:2018-12-29 04:43:49
【问题描述】:

我在网上搜索过,但找不到任何符合我的情况。情况如下。

我正在使用聚合将一个集合和一个来自另一个集合的文档组合在一起

restaurants.aggregate([
  {
    $match: {
      _id: {
        $in: idList
      }
    }
  },
  {
    $lookup: {
      from: "tags",
      localField: "details.restaurantType",
      foreignField: "details.restaurantType._id",
      as: "types"
    }
  },
  {
    $project: {
      restaurantName: "$details.restaurantName",
      restaurantType: "$details.restaurantType",
      type: {
        $filter: {
          input: "$types",
          as: "type",
          cond: {
            $eq: ["$$type._id", "$details.restaurantType"]
          }
        }
      },
      currency: "$details.currency",
      costPerPax: "$details.costPerPax"
    }
  }
]);

当前结果

我当前结果中的“类型”字段是 [],我需要一个匹配的值

[
    {
        "id": "5c20c7a0036dda80a8baabcc",
        "restaurantName": "Villagio Restaurant Sutera Mall",
        "type": [],
        "currency": "RM",
        "costPerPax": 22,
    },
    {
        "id": "5c20ceb07715216d3c217b7a",
        "restaurantName": "Thai Food Thai Now Sutera Mall",
        "type": [],
        "currency": "RM",
        "costPerPax": 16,
    }
]

预期结果

我需要“类型”字段与来自另一个集合的匹配标记名称,例如这样

[
    {
        "id": "5c20c7a0036dda80a8baabcc",
        "restaurantName": "Villagio Restaurant Sutera Mall",
        "type": "Western",
        "currency": "RM",
        "costPerPax": 22,
    },
    {
        "id": "5c20ceb07715216d3c217b7a",
        "restaurantName": "Thai Food Thai Now Sutera Mall",
        "type": "Thai",
        "currency": "RM",
        "costPerPax": 16,
    }
]

额外信息

餐厅收藏的两份文件

    {
        "details": {
            "restaurantName": "Villagio Restaurant Sutera Mall",
            "restaurantType": "5c01fb57497a896d50f498a8"
        },
        "_id": "5c20c7a0036dda80a8baabcc",
        "status": "OP",
        "__v": 0
    },
    {
        "details": {
            "restaurantName": "Kingshahi Japanese Shop",
            "restaurantType": "5c01fb57497a896d50f49879"
        },
        "_id": "5c20cb4fb7e75180480690c2",
        "status": "OP",
        "__v": 0
    } 

标签集合中的一个文档

        {
            "_id": "5c01fb57497a896d50f49876",
            "details": {
                "restaurantTypeId": "5c01fb57497a896d50f49877",
                "restaurantTypes": [
                    {
                        "_id": "5c01fb57497a896d50f49879",
                        "name": "Asian",
                        "counter": 1
                    },
                    {
                        "_id": "5c01fb57497a896d50f4987a",
                        "name": "Bakery",
                        "counter": 0
                    }
                ]
            }
        }

【问题讨论】:

  • 您的foreignField 值不正确。应该是foreignField: "details.restaurantTypes._id",
  • 哇,谢谢,现在我设法从数据库中获取了一些结果,但是我在每个返回对象的“类型”字段中获得了整个标签文档,我尝试了过滤器,但它给了我 []在结果中。您在我的 $filter 查询中看到任何错误吗?
  • 您的 foreignField 是一个数组,这就是您获取整个标签元素的原因。顺便说一句,您使用的是什么版本的 mongo?
  • 我使用的是数据库版本v4.0.4
  • 我想我需要更多时间才能从数据库中获取结果。我会在 10 分钟后回来

标签: node.js mongodb mongodb-query aggregation-framework


【解决方案1】:

您可以使用以下优化的聚合管道

db.restaurants.aggregate([
  { "$lookup": {
    "from": "tags",
    "let": { "restaurantType": "$details.restaurantType" },
    "pipeline": [
      { "$match": {
        "$expr": { "$in": ["$$restaurantType", "$details.restaurantTypes._id"] }
      }},
      { "$unwind": "$details.restaurantTypes" },
      { "$match": {
        "$expr": { "$eq": ["$details.restaurantTypes._id", "$$restaurantType"] }
      }}
    ],
    "as": "types"
  }},
  { "$project": {
    "restaurantName": "$details.restaurantName",
    "restaurantType": "$details.restaurantType",
    "type": { "$arrayElemAt": ["$types.details.restaurantTypes.name", 0] },
    "currency": "$details.currency",
    "costPerPax": "$details.costPerPax"
  }}
])

【讨论】:

  • 嗨,很酷的答案!将其添加到我的查询时出现此错误,您介意看一下吗? :) 错误:MongoError: $in 需要一个数组作为第二个参数,发现:缺失
  • 因为您的某些字段可能不包含 restarantTypes 数组。你能看看stackoverflow.com/questions/51642472/…
  • 哇,哈哈哈我已经改变了我的数据库。我没有检查最新的答案,但前一个像魔术一样工作:) 非常感谢!我看到你的名字出现在每一个地方,我感谢你的帮助!你是MongoDB的天才!
猜你喜欢
  • 1970-01-01
  • 2020-06-07
  • 2023-02-09
  • 1970-01-01
  • 1970-01-01
  • 2014-09-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多