你真的不需要的 JavaScript的评价这里,只使用基本的查询操作符与$elemMatch
查询数组。虽然这里的“价值”元素实际上是字符串,但这不是真正的重点(正如我在本文末尾解释的那样)。主要的一点是,以得到它在第一时间:
collection.find(
{
"ingredients": {
"$elemMatch": {
"name": "ingredient1",
"value": { "$gt": 50 }
}
}
},
{ "ingredients.$": 1 }
)
在第二部分的$
是postional operator,突出只从查询条件的阵列的匹配元素。
这比JavaScript评估速度快得多,因为评估代码不需要编译并使用本机编码的运算符,并且可以在“名称”上使用“索引”,甚至数组的“值”元素有助于过滤匹配。
如果您希望阵列中有多个匹配项,那么.aggregate()
命令是最佳选择。随着现代MongoDB的版本,这是很简单的:
collection.aggregate([
{ "$match": {
"ingredients": {
"$elemMatch": {
"name": "ingredient1",
"value": { "$gt": 50 }
}
}
}},
{ "$redact": {
"$cond": {
"if": {
"$and": [
{ "$eq": [ { "$ifNull": [ "$name", "ingredient1" ] }, "ingredient1" ] },
{ "$gt": [ { "$ifNull": [ "$value", 60 ] }, 50 ] }
]
},
"then": "$$DESCEND",
"else": "$$PRUNE"
}
}}
])
即使simplier在即将发行的这些介绍$filter
操作:
collection.aggregate([
{ "$match": {
"ingredients": {
"$elemMatch": {
"name": "ingredient1",
"value": { "$gt": 50 }
}
}
}},
{ "$project": {
"ingredients": {
"$filter": {
"input": "$ingredients",
"as": "ingredient",
"cond": {
"$and": [
{ "$eq": [ "$$ingredient.name", "ingredient1" ] },
{ "$gt": [ "$$ingredient.value", 50 ] }
]
}
}
}
}}
])
凡在这两种情况下,你都有效地“过滤”那些数组元素不符合初始文件匹配后的条件。另外,由于您的“价值”现在实际上是“字符串”,因此您应该将其更改为数字。这里是一个基本的过程:
var bulk = collection.initializeOrderedBulkOp(),
count = 0;
collection.find().forEach(function(doc) {
doc.ingredients.forEach(function(ingredient,idx) {
var update = { "$set": {} };
update["$set"]["ingredients." + idx + ".value"] = parseFloat(ingredients.value);
bulk.find({ "_id": doc._id }).updateOne(update);
count++;
if (count % 1000 != 0) {
bulk.execute();
bulk = collection.initializeOrderedBulkOp();
}
})
]);
if (count % 1000 != 0)
bulk.execute();
而且这将修复数据,所以这里的查询形式工作。
这比使用JavaScript $where
进行处理要好得多,它需要评估集合中的每个文档,而没有筛选索引的好处。如果正确的格式是:
collection.find(function() {
return this.ingredients.some(function(ingredient) {
return (
(ingredient.name === "ingredient1") &&
(parseFloat(ingredient.value) > 50)
);
});
})
而且,也不能在结果中“投射”匹配的值,因为其他格式可以。
我在这里指出,你的 “价值” 项事实上是字符串。因此,在“500”下进行基本的词汇比较是可行的(字符串方式),但在存储中将其转换为数字更好。 –