【问题标题】:Mongo Match number that "begins with" query in an array of numbersMongo匹配数字数组中“开头”查询的数字
【发布时间】:2016-05-05 04:52:27
【问题描述】:

在 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/ ] } } )

【问题讨论】:

  • 你的意思是numbers数组中的第一个数字吗?如果numbers 中的那些元素是浮点数,您的正则表达式也将不起作用。要使用正则表达式,您的数组元素必须是字符串。
  • 你的正则表达式也有一个负号,所以它只会匹配-87,这是你想要的吗?
  • @user3100115 是的。因此,这里的解决方案是查看“字符串化”数值,或者更好地考虑“范围”中的所有可能值,以了解数字的“开始”。取决于这意味着什么。

标签: regex mongodb mongodb-query


【解决方案1】:

您的方法在这里有两个误解。首先是正则表达式只适用于字符串而不适用于数值。 JavaScript 是一种语言实现的示例,它将“字符串化”数值以进行比较,但这是基本过程。稍后再说。

另一个误解似乎是$in的使用。您不需要该运算符“仅”对数组元素执行测试,而是相反,您可以提供一个值数组来测试字段(单个值或数组) .这基本上是$or 条件的简写形式,用于测试同一字段上的多个值。由于只有一个值要测试,因此您可能不需要它。

如果您的意图是匹配“以”“87”值“开头”的文档,那么您可以使用 $where 的 JavaScript 评估。虽然这不是最理想的做法,但由于无法在匹配中使用索引,并且提供的函数必须针对整个集合或至少其他查询参数的结果进行暴力测试:

db.TestCollection.find(
    function() {
        return this.numbers.some(function(el) {
            return /^87/.test(el);
        });
    }
)

直接向.find() 提供function 参数是$where 的shell“快捷方式”,但您也可以将长格式与任何提供JavaScript 表达式的字符串一起使用以返回true/false。还要注意插入符号^ 是用于正则表达式中“开始于”的正确元素。 JavaScript 在此处“字符串化”,因此测试将返回 true。

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

db.TestCollection.find({
    "numbers": { "$gte": 87, "$lt": 88 }
})

因此,$gte$lt 运算符以最有效的方式为所有可能的浮点组合以 87 开头限定了范围。当然,您只需要应用数组元素进行测试,所有元素都会被检查。

因此,在寻找“以”开头的数字时,最好考虑数字“范围”而不是求助于正则表达式。

【讨论】:

    【解决方案2】:

    参考this

    MongoDB 正则表达式功能,用于在查询中进行模式匹配字符串。我们已经考虑过这一点,但不要认为允许针对非字符串字段的正则表达式是一个好主意。这将非常缓慢,并且有点误导。

    我们可以通过$where做到这一点

    > db.TestColleciton.find({$where: 'return this.numbers.some(function(n){ return /^87.*/.test(n);})'})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-31
      • 1970-01-01
      • 1970-01-01
      • 2014-01-15
      相关资源
      最近更新 更多