在 mongo shell 中,我正在尝试查询数字数组
一个示例对象:
[{"name":"test", "numbers" : [76.3922, 42.9196154]},
{"name":"test", "numbers" : [87.938547, 42.9196154]},
{"name":"test", "numbers" : [42.9196154,87.938547]}]
我试图使用它来查找任何以 87 开头的数字的文档
db.TestColleciton.find( { "numbers": { $in: [ /^-87/ ] } } )
你在这里的方法有两个误解。首先,正则表达式只适用于字符串,而不适用于数值。JavaScript 是一种语言实现的示例,它将"字符串化"数值进行比较,但这是基本过程。以后再说。
另一个误解似乎是使用$in
。您不需要该运算符"只是"对数组元素执行测试,而是相反,您可以在其中提供值数组以针对字段(单个值或数组)进行测试。这基本上是$or
条件的简写形式,用于测试同一字段上的多个值。由于只有一个值要测试,因此此处可能不需要它。
如果您的目的是匹配"以"87"值"开头"的文档,则可以使用 JavaScript $where
评估。虽然这不是最好的做法,因为不能在匹配中使用索引,并且必须通过针对整个集合的蛮力测试所提供的函数,或者至少测试其他查询参数的结果:
db.TestCollection.find(
function() {
return this.numbers.some(function(el) {
return /^87/.test(el);
});
}
)
直接向.find()
提供function
参数是$where
的外壳"shorcut",但您也可以将长格式与任何提供JavaScript表达式的字符串一起使用以返回true/false
。另请注意,插入符号^
是正则表达式中用于"开头为"的正确元素。JavaScript 在这里"字符串化",所以测试将返回 true。
但是在这里使用自然查询运算符的更好情况是性能更高,基本上是查找 87
和 88
之间的所有值。这将以有效的方式返回所有浮点变化:
db.TestCollection.find({
"numbers": { "$gte": 87, "$lt": 88 }
})
因此,$gte
和 $lt
运算符以最有效的方式绑定了从 87
开始的所有可能的浮点组合的范围。当然,您只需要应用数组元素进行测试,所有元素都将被输入。
因此,在寻找"开头"的数字时,最好查看数字"范围"考虑因素,而不是诉诸正则表达式。
参考这个
MongoDB 正则表达式功能,用于查询中的模式匹配字符串。我们已经考虑过这一点,但不要认为允许正则表达式针对非字符串字段是一个好主意。它会非常慢,而且有点误导。
我们可以通过$where来做到这一点
> db.TestColleciton.find({$where: 'return this.numbers.some(function(n){ return /^87.*/.test(n);})'})