我很难写Mongo查询。我永远无法理解为什么它没有返回我所期望的,是的,我正在阅读文档,但显然是愚蠢的理解。
在Compass中,我用一个包含城市的文档数组来查询State集合。
{"Cities.CityName"Denver"
这将返回给我一个State of Colorado文档,其中包含文档数组中的所有城市。下面的示例只显示了一个城市文档,但它们都在那里。
{
"_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}
但这总是返回给我的状态文档id,而不是匹配的城市文档_id。
我做错了什么?
1)您可以使用$(投影)或$elemMatch(投影):
-
用例:位置$操作符将
<array>
的内容限制为返回符合数组查询条件的第一个元素。 -
,
{ "Cities.$": 1 }
或{"Cities": { "$elemMatch": { "CityName": "Denver" } } }
-
结果:
{
"_id":{"$oid":"6146ada531696ee91a3f9fa4"},
"Cities":[{
"_id":{"$oid":"6146ada531696ee91a3f5a50"},
"CityName":"Denver",
"Latitude":"39.55666000",
"Longitude":"-104.89609000"
}]
}
游乐场
注意:您必须在投影中指定所需的结果字段!
2)你可以使用$filter聚合操作符,从MongoDB 4.4在find()
方法支持:
用例:根据指定的条件选择要返回的数组子集。返回一个仅包含符合条件的元素的数组。返回的元素保持原来的顺序。
,
{
"Cities": {
"$filter": {
"input": "$Cities",
"cond": { "$eq": ["$$this.CityName", "Denver"] }
}
}
}
- 结果:
{
"_id":{"$oid":"6146ada531696ee91a3f9fa4"},
"Cities":[{
"_id":{"$oid":"6146ada531696ee91a3f5a50"},
"CityName":"Denver",
"Latitude":"39.55666000",
"Longitude":"-104.89609000"
}...{}]
}
游乐场
注意:您必须在投影中指定所需的结果字段!
2.1)您可以使用$map
聚合运算符从Cities
数组中只选择_id
:
用例:对数组中的每一项应用表达式,并返回具有应用结果的数组。
,
{
"Cities": {
"$map": {
"input": {
"$filter": {
"input": "$Cities",
"cond": { "$eq": ["$$this.CityName", "Denver"] }
}
},
"in": "$$this._id"
}
}
}
- 结果:
{
"_id":{"$oid":"6146ada531696ee91a3f9fa4"},
"Cities":[
{"$oid":"6146ada531696ee91a3f5a50"},
{"$oid":"6146ada531696ee91a3f5a51"},
....
]
}
游乐场
注意:您必须在投影中指定所需的结果字段!
3)您可以使用聚合方法aggregate()进行更多定制:
- ex:
$match
检查查询条件$addFields
添加或格式化现有属性$filter
和$map我已经在2)点 中解释过了
db.collection.aggregate([
{ "$match": { "Cities.CityName": "Denver" } },
{
"$addFields": {
"Cities": {
"$map": {
"input": {
"$filter": {
"input": "$Cities",
"cond": { "$eq": ["$$this.CityName", "Denver"] }
}
},
"in": "$$this._id"
}
}
}
}
])
游乐场
- 结果:
[
{
"Cities": [
ObjectId("6146ada531696ee91a3f5a50")
],
"StateCode": "CO",
"StateName": "Colorado",
"_id": ObjectId("6146ada531696ee91a3f9fa4")
}
]