MongoDB:根据文档中的另一个属性从数组中选择元素 [英] MongoDB: Select element from array based on another property in the document
问题描述
我有一个MongoDB集合,其中包含以下结构的文档(省略了无趣的部分):
I have a MongoDB collection with documents of the following structure (non-interesting bits left out):
{
displayFieldId: "abcd",
fields: [
{
fieldId: "efgh",
value: "cake"
},
{
fieldId: "abcd",
value: "cheese"
},
....
],
....
}
我想对此集合运行查询,以仅获取fields
数组中与文档的displayFieldId
匹配的fields
数组中的元素.因此,对以上文档的查询结果应为:
I would like to run a query on this collection to fetch only the element in the fields
array which fieldId
matches the document's displayFieldId
. The result of the query on the document above should thus be:
{
fields: [
{
fieldId: "abcd",
value: "cheese"
}
],
....
}
我构造了以下查询.它符合我的要求,但displayFieldValue
是硬编码的
I constructed the following query. It does what I want, with the exception that the displayFieldValue
is hard coded
db.containers.find({}, {
fields: {
$elemMatch: {
fieldId: "abcd"
}
}
});
有没有办法让它查看文档的displayFieldId
并使用该值而不是硬编码的"abcd"
?
Is there a way to make it look at the document's displayFieldId
and use that value instead of the hard coded "abcd"
?
服务器正在运行MongoDB 3.2.6
The server is running MongoDB 3.2.6
如果可能的话,我想在不进行聚合的情况下执行此操作,但是如果无法完成,则必须进行聚合
If possible, I would like to do this without aggregation, but if that can't be done, then aggregation will have to do
推荐答案
使用聚合框架:
db.containers.aggregate([
{
"$redact": {
"$cond": [
{
"$anyElementTrue": [
{
"$map": {
"input": "$fields",
"as": "el",
"in": {
"$eq": ["$$el.fieldId", "$displayFieldId"]
}
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
},
{
"$project": {
"displayFieldId": 1,
"fields": {
"$filter": {
"input": "$fields",
"as": "el",
"cond": {
"$eq": ["$$el.fieldId", "$displayFieldId"]
}
}
},
"otherfields": 1,
....
}
}
])
MongoDB 3.4 :
db.containers.aggregate([
{
"$redact": {
"$cond": [
{
"$anyElementTrue": [
{
"$map": {
"input": "$fields",
"as": "el",
"in": {
"$eq": ["$$el.fieldId", "$displayFieldId"]
}
}
}
]
},
"$$KEEP",
"$$PRUNE"
]
}
},
{
"$addFields": {
"fields": {
"$filter": {
"input": "$fields",
"as": "el",
"cond": {
"$eq": ["$$el.fieldId", "$displayFieldId"]
}
}
}
}
}
])
没有聚合框架-使用 $where
(慢速查询):
Without aggregation framework - using $where
(the slow query):
db.containers.find({
"$where": function() {
var self = this;
return this.fields.filter(function(f){
return self.displayFieldId === f.fieldId;
}).length > 0;
}
}).map(function(doc){
var obj = doc;
obj.fields = obj.fields.filter(function(f){
return obj.displayFieldId === f.fieldId;
});
return obj;
})
这篇关于MongoDB:根据文档中的另一个属性从数组中选择元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!