Mongodb 查找嵌套数组中匹配条件的第一个元素
我有以下文件:Mongodb 查找嵌套数组中匹配条件的第一个元素,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有以下文件: doc1: { 'array': [ {'field': 'ABC', 'enabled': 'false'}, {'field': 'BCD', 'enabled': 'true'}, {'field': 'DEF', 'enabled': 'false'}, {'field': 'XYZ', 'enabled': 'true'}, ] } doc2: { 'array': [ {'field': 'ABC', 'en
doc1: {
'array': [
{'field': 'ABC', 'enabled': 'false'},
{'field': 'BCD', 'enabled': 'true'},
{'field': 'DEF', 'enabled': 'false'},
{'field': 'XYZ', 'enabled': 'true'},
]
}
doc2: {
'array': [
{'field': 'ABC', 'enabled': 'true'},
{'field': 'BCD', 'enabled': 'true'},
{'field': 'DEF', 'enabled': 'false'},
{'field': 'XYZ', 'enabled': 'true'},
]
}
我正在按特定字段执行搜索。
我想获取启用此字段的所有文档,并且在此之前(列表中)没有启用其他字段
例如:
搜索字段:BCD
,enabled:true-应仅返回第一个文档(因为在第二个文档中,ABC
也已启用)
搜索XYZ
,enabled:true-不应返回任何文档,因为此列表顶部有其他启用的字段
我试图用$elemMatch
进行smth,但我不知道是否可以在elemMatch
匹配的元素上应用过滤器
有什么建议吗?为什么不通过启用的
字段进行搜索,然后检查字段是否合适
db.collection("col").findOne({
"array.enabled": true
}, {
array: {
$elemMatch {
enabled: true
}
}
})
.then(function(docs){
docs.forEach(function(doc){
if(doc.array[0].field == "ABC"){
// Ok, we get it
}
})
})
find
的第二个参数是投影,所以应用程序不会从文档中下载完整的数组,而只下载它的第一个匹配元素。有$where
关键字,允许为类似目的生成复杂条件
find($where:'this.array.filter(函数(e){returne e.enabled==“true”})[0]。field==“ABC”)
由于这不使用任何索引,我将添加更多条件以从优化中获益。除了使用常规查询外,最好使用搜索,并且仍将内容保留在服务器上:
db.getCollection('collection').find({
"array": {
"$elemMatch": { "field": "BCD", "enabled": "true" },
},
"$where": function() {
return this.array.map((e,i) => Object.assign(e,{ i }))
.filter( e => e.field === "BCD" && e.enabled === "true" )
.map( e => e.i )[0] <=
this.array.map(e => e.enabled).indexOf("true")
}
})
因此,实际上并没有实际的查询操作来强制执行该操作,但这两种情况都将选择保留在“服务器上”,而不是通过线路将数据发送到客户端,然后进行过滤
因为如果你这样做的话,首先就否定了使用数据库的目的。因此,您确实希望这种情况发生在服务器上
db.getCollection('collection').aggregate([
{ "$match": {
"array": {
"$elemMatch": { "field": "BCD", "enabled": "true" },
}
}},
{ "$redact": {
"$cond": {
"if": {
"$lte": [
{ "$arrayElemAt": [
{ "$map": {
"input": {
"$filter": {
"input": {
"$map": {
"input": {
"$zip": {
"inputs": [
"$array",
{ "$range": [0, { "$size": "$array" }] }
]
}
},
"as": "a",
"in": {
"field": { "$arrayElemAt": [ "$$a.field", 0 ] },
"enabled": { "$arrayElemAt": [ "$$a.enabled", 0 ] },
"index": { "$arrayElemAt": [ "$$a", 1 ] }
}
}
},
"as": "a",
"cond": {
"$and": [
{ "$eq": [ "$$a.field", "BCD" ] },
{ "$eq": [ "$$a.enabled", "true" ] }
]
}
}
},
"as": "a",
"in": "$$a.index"
}},
0
]},
{ "$indexOfArray": [ "$array.enabled", "true" ] }
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])