Mongo 文档数组的项目 _id

Mongo Project _id of Array of Documents

我很难写 Mongo 查询。我永远无法理解为什么它没有 return 我所期望的,是的,我正在阅读文档,但显然很难理解。

在 Compass 中,我为带有城市文档数组的 State 集合编写了这个查询。

{"Cities.CityName":"丹佛"}

这 return 对我来说是科罗拉多州文档,其中包含文档数组中的所有城市。我下面的示例只显示了一份城市文件,但它们都在那里。

{
"_id": {"$oid":"6146ada531696ee91a3f9fa4"},
"StateName": "Colorado",
"StateCode": "CO",
"Cities": [{
    "_id": {"$oid":"6146ada531696ee91a3f5a50"},
    "CityName": "Denver",
    "Latitude": "39.55666000",
    "Longitude": "-104.89609000"
    }...]
}

好的,我想清楚了,我们在 CityName 上进行了匹配,现在只需投影 City 文档的 _id。

{"Cities._id":1}

但这对我来说总是 return 州文档 id 而不是匹配的城市文档 _id。

我做错了什么?

1) 您可以使用 $ (projection) or $elemMatch (projection):

  • 用例: 位置 $ 运算符将 <array> 的内容限制为 return 与查询匹配的第一个元素数组条件。

  • 例如: { "Cities.$": 1 }{"Cities": { "$elemMatch": { "CityName": "Denver" } } }

  • 结果:

{
 ​"_id":{"$oid":"6146ada531696ee91a3f9fa4"},
 ​"Cities":[{
   ​"_id":{"$oid":"6146ada531696ee91a3f5a50"},
   ​"CityName":"Denver",
   ​"Latitude":"39.55666000",
   ​"Longitude":"-104.89609000"
 ​}]
}

Playground

Note: You have to specify the required result fields in the projection!

2) 您可以使用 $filter 聚合运算符,从 MongoDB 4.4 开始支持 find() 方法:

  • use case: 根据指定条件选择数组的子集到return。 Returns 仅包含符合条件的元素的数组。 returned 元素按原始顺序排列。

  • 例如:

{ 
  "Cities": { 
    "$filter": { 
      "input": "$Cities", 
      "cond": { "$eq": ["$$this.CityName", "Denver"] } 
    } 
  } 
}
  • 结果:
{
 ​"_id":{"$oid":"6146ada531696ee91a3f9fa4"},
 ​"Cities":[{
   ​"_id":{"$oid":"6146ada531696ee91a3f5a50"},
   ​"CityName":"Denver",
   ​"Latitude":"39.55666000",
   ​"Longitude":"-104.89609000"
 ​}...{}]
}

Playground

Note: You have to specify the required result fields in the projection!

2.1) 您可以使用 $map 聚合运算符来 select 来自 Cities 数组的 _id

  • 用例: 将表达式应用于数组中的每个项目,并 return 是一个包含应用结果的数组。

  • 例如:

{ 
  "Cities": { 
    "$map": {
      "input": {
        "$filter": { 
          "input": "$Cities", 
          "cond": { "$eq": ["$$this.CityName", "Denver"] } 
        }
      },
      "in": "$$this._id"
    }
  } 
}
  • 结果:
{
  "_id":{"$oid":"6146ada531696ee91a3f9fa4"},
  "Cities":[
    {"$oid":"6146ada531696ee91a3f5a50"},
    {"$oid":"6146ada531696ee91a3f5a51"},
    ....
  ]
}

Playground

Note: You have to specify the required result fields in the projection!

3) 您可以使用聚合方法 aggregate() 进行更多自定义:

- 例如:

  • $match检查查询条件
  • $addFields 添加或格式化现有属性
  • $filter 和 $map 我已经在 2) point
  • 中解释过了
db.collection.aggregate([
  { "$match": { "Cities.CityName": "Denver" } },
  {
    "$addFields": {
      "Cities": {
        "$map": {
          "input": {
            "$filter": {
              "input": "$Cities",
              "cond": { "$eq": ["$$this.CityName", "Denver"] }
            }
          },
          "in": "$$this._id"
        }
      }
    }
  }
])

Playground

  • 结果:
[
  {
    "Cities": [
      ObjectId("6146ada531696ee91a3f5a50")
    ],
    "StateCode": "CO",
    "StateName": "Colorado",
    "_id": ObjectId("6146ada531696ee91a3f9fa4")
  }
]