我当前的方法是:
var v = 'Value';
Collection.find({arrayToLookIn: v}).forEach(function(obj) {
if (obj.arrayToLookIn.indexOf(v) !== obj.arrayToLookIn.length - 1) {
// do stuff
}
}
我想知道是否有一种方法可以在find()
调用中指定这样的规则,而无需进行内部检查?
我浏览了https://docs.mongodb.org/manual/tutorial/query-documents/#match-an-array-element,但没有发现我所寻找的东西。
第一个问题,请保持温柔:)
您需要$where
,可以使用JavaScript评估来匹配文档。因此,您在这里要求评估代码测试每个数组元素,而不是最后一个:
Collection.find({
"arrayToLookIn": v,
"$where": function() {
var array = this.arrayToLookIn;
array.pop(); // remove last element
return array.some(function(el) { return el == 'Value' });
}
})
请注意,由于它是JavaScript发送到服务器的,因此需要在该代码中指定“值”,而不是使用变量。您可以选择将JavaScript代码构造为“字符串”,以将该变量作为文字加入其中,并将其作为参数提交给$where
。
请注意,我将保留基本的等式匹配项,因为$where
使用这样的索引无法进行匹配,因此它的工作是“过滤”出匹配项在最后一个元素上的结果,而不是测试每个文档来查找是否甚至还在那里。
令人好奇的是,截至当前的MongoDB 3.0版本系列,还没有一种真正有效的方法来使用聚合框架,因此JavaScript评估是更好的选择。
您现在需要做一些愚蠢的事情,例如在$group
after之后找到最后一个元素$unwind
,然后再$match
逐个列出值$unwind
。如果值存在多次,效率不高且容易出错。
将来的发行版中将有一个$slice
运算符,可以将其与一起使用$redact
:
Collection.aggregate([
// Still wise to do this as mentioned earlier
{ "$match": { "arrayToLookIn": v } },
// Then only return if the match was not in the last element
{ "$redact": {
"$cond": {
"if": {
"$setIsSubset": [
[v],
{ "$slice": [
"$arrayToLookIn",
0,
{ "$subtract": [ { "$size": "$arrayToLookIn" }, 1 ] }
]}
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
在哪里$setIsSubset
做这已经通过删除它的最后一个数据阵列的比较$slice
仅返回从元素0
到$size
零下1
。
并且$where
,当下一个具有$slice
聚合功能的版本可用时,它应该比使用本机编码操作进行比较更为有效。
更不用说$unwind
还可以选择在以后的版本中包括索引位置。但是即使添加了它,也不是一个很好的选择。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句