我有一个MongoDB集合,其中包含以下结构的文档(遗漏了无趣的内容):
{
displayFieldId: "abcd",
fields: [
{
fieldId: "efgh",
value: "cake"
},
{
fieldId: "abcd",
value: "cheese"
},
....
],
....
}
我想对此集合运行查询,仅获取fields
数组中fieldId
与文档displayFieldId
匹配的元素。因此,对上述文件的查询结果应为:
{
fields: [
{
fieldId: "abcd",
value: "cheese"
}
],
....
}
我构造了以下查询。除了displayFieldValue
是硬编码的
db.containers.find({}, {
fields: {
$elemMatch: {
fieldId: "abcd"
}
}
});
有没有办法让它查看文档displayFieldId
并使用该值而不是硬编码的"abcd"
?
服务器正在运行MongoDB 3.2.6
如果可能的话,我想在没有聚合的情况下这样做,但如果不能做到,那么聚合将不得不做
答案 0 :(得分:2)
使用聚合框架:
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
(慢查询):
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;
})