蒙戈 在数字数组中"begins with"查询的匹配号码



在 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。

但是在这里使用自然查询运算符的更好情况是性能更高,基本上是查找 8788 之间的所有值。这将以有效的方式返回所有浮点变化:

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);})'})

最新更新