【问题标题】:Use only limited keys from $lookup aggregation仅使用 $lookup 聚合中的有限键
【发布时间】:2017-07-14 06:14:38
【问题描述】:

我想在 $lookup 聚合之后过滤数据。

现在,我想要子集合中位置键的唯一值,而不是整个文档。另外,如果我需要位置中的特定密钥,即 zone_id 我该怎么办?请帮忙。

我正在使用以下查询

// 查询

db.parent.aggregate([
        {
          $lookup:
        {
          from: "child",
          localField: "pid",
          foreignField: "pid",
          as: "more"
        } 
       }
])

// 数据 // 子集合

 db.child.insert({
  "pid": 1,
  "name": "Max",
  "title": "Top" 
  "status": 1,

  "description": {
    "destination": "jur bagh",
    "community": "abc"
  },
  "location:": {
    "zone_id": "north",
    "city": "jaipur",
    "latitude": "12.121212",
    "longitude": "21.414134"
  }, 
  "created_by": "user_id",
  "modified_by": "user",
  "created_at": "12:00",
  "updated_at": "13:00"
});

//父集合

 db.parent.insert({
  "pid": 1,
  "pname": "PQW",
  "rox": "Labs",
  "status": 1,
  "created_by": "smdcd",
  "modified_by": "pink",
  "created_at": "12:00",
  "updated_at": "13:00"
});

我想要这样的结果

db.parent.insert({
  "pid": 1,
  "pname": "PQW",
  "rox": "Labs",
  "status": 1,
  "created_by": "smdcd",
  "modified_by": "pink",
  "created_at": "12:00",
  "updated_at": "13:00"
"more" [
"location:": {
    "zone_id": "north",
    "city": "jaipur",
    "latitude": "12.121212",
    "longitude": "21.414134"
  }
]


});

【问题讨论】:

  • 请注意,您的子集合数据中似乎存在“错字”。该字段名为"location:",名称末尾包含冒号:。目前尚不清楚这是否只是问题中的错误,或者您的实际数据是否包含此错误。因此,“错误”被认为是响应。

标签: mongodb mongodb-query aggregation-framework


【解决方案1】:

您希望$arrayElemAt 在此处引用来自$lookup 的“单个”结果,并在可用的情况下使用$addFields$project 将您的新字段放入文档中的所有字段:

db.parent.aggregate([
  { "$lookup": {
    "from": "child",
    "localField": "pid",
    "foreignField": "pid",
    "as": "location"  
  }},
  { "$addFields": {
      "location": { "$arrayElemAt": [ "$location.location:", 0 ] }
  }}
])

另请注意,您的子字段名称似乎有错字,因为它被称为:"location:",末尾有冒号:。或者也许这只是问题的一个错误。

生产:

{
    "_id" : ObjectId("5968821f7dcd6a5f6a9b4b7d"),
    "pid" : 1.0,
    "pname" : "PQW",
    "rox" : "Labs",
    "status" : 1.0,
    "created_by" : "smdcd",
    "modified_by" : "pink",
    "created_at" : "12:00",
    "updated_at" : "13:00",
    "location" : {
        "zone_id" : "north",
        "city" : "jaipur",
        "latitude" : "12.121212",
        "longitude" : "21.414134"
    }
}

根据您问题中提供的数据。

如果您确实想要多个结果,请交替处理 $map

db.parent.aggregate([
  { "$lookup": {
    "from": "child",
    "localField": "pid",
    "foreignField": "pid",
    "as": "more"  
  }},
  { "$addFields": {
    "more": {
      "$map": {
        "input": "$more.location:",
        "as": "l",
        "in": { "location": "$$l" }
      }
    }
  }}
])

结果如下:

{
    "_id" : ObjectId("5968821f7dcd6a5f6a9b4b7d"),
    "pid" : 1.0,
    "pname" : "PQW",
    "rox" : "Labs",
    "status" : 1.0,
    "created_by" : "smdcd",
    "modified_by" : "pink",
    "created_at" : "12:00",
    "updated_at" : "13:00",
    "more" : [ 
        {
            "location" : {
                "zone_id" : "north",
                "city" : "jaipur",
                "latitude" : "12.121212",
                "longitude" : "21.414134"
            }
        }
    ]
}

【讨论】:

  • 请注意 $addFields 仅适用于 MongoDB v3.4。
  • @PavK。非常清楚这一点,这就是为什么我说“在可用的地方”。无论如何,它几乎没有什么区别,只是列出“所有”字段与1 以通过$project 包含或使用$addFields 之间的区别。答案的基本内容因版本而异。无论如何,$lookup 至少需要 MongoDB 3.2,而 3.4 并不完全是“新版本”。
  • @NeilLunn 当我在 ubuntu 中键入 mongo 时,它显示 MongoDB shell 版本 v3.4.6 连接到:mongodb://127.0.0.1:27017 MongoDB 服务器版本:3.2.15 警告:shell 和服务器版本可以不匹配仍然无法识别 $addfields
  • @Creator 因为“shell”版本是什么并不重要,而是“服务器”版本决定了哪些运算符被识别。如前所述,答案仍然基本相同,除了您必须使用$project 并因此明确包含您想要包含的所有其他字段。您的“服务器”是 MongoDB 3.2。由于它位于localhost 上,听起来您最近安装但从未重新启动服务器实例。如果这是您所做的,则重新启动服务器,以便执行新的 3,4 版本。 Unix 就是这样工作的。
  • @NeilLunn 感谢您的精彩解释,希望对其他开发者也有帮助
【解决方案2】:

使用 $project https://docs.mongodb.com/manual/reference/operator/aggregation/project/

,{$project:{
  pid:1,
  pname:1,
  rox:1,
  status:1,
  modified_by:1,
  created_by:1,
  created_at:1,
  updated_at:1,
  more.location:$more.location
}}
// 'name of the field':1 means you want to keep the 'name'.
//  more.location:$more.location means you passing down the data you need.

要过滤结果,您可以将 $match 添加到聚合中 https://docs.mongodb.com/manual/reference/operator/aggregation/match/

,{$match:{
    more.location.zone_id:'north'
}}

如果您有多个位置作为数组但只想返回一个,您可能需要先 $unwind 数组:

,{$unwind:'$more.location'}

【讨论】:

  • 它给了我错误: SyntaxError: missing : after property id @(shell) db.parent.aggregate([ { $lookup: { from: "child", localField: "pid", foreignField: "pid", as: "more" } }, {$project:{ pid:1, pname:1, rox:1, status:1, modified_by:1, created_by:1, created_at:1, updated_at:1, 更多.location:$more.location }} ])
猜你喜欢
  • 2019-04-18
  • 2016-10-14
  • 1970-01-01
  • 1970-01-01
  • 2018-02-01
  • 1970-01-01
  • 2022-01-05
  • 2021-06-04
  • 2023-03-09
相关资源
最近更新 更多