【问题标题】:Improve the performce of a MongoDB query which uses a "$where" expression提高使用“$where”表达式的 MongoDB 查询的性能
【发布时间】:2017-09-04 16:18:05
【问题描述】:

我需要在 MongoDB 服务器上运行以下查询:

QUERY = {
    "$and" : [
        {"x" : {'$gt' : 1.0}},
        {"y" : {'$gt' : 0.1}},
        {"$where" : 'this.s1.length < this.s2.length+3'}
    ]
}

此查询非常慢,因为服务器需要对集合中的每个文档执行 JavaScript 表达式。

有什么办法可以优化吗?

我考虑过使用$size 运算符,但我不确定它是否适用于字符串,而且我更不确定如何比较它在一对字符串上的输出(就像这里的情况一样)。

这是我的脚本的其余部分,以备不时之需:

from pymongo import MongoClient

USERNAME        = ...
PASSWORD        = ...
SERVER_NAME     = ...
DATABASE_NAME   = ...
COLLECTION_NAME = ...

uri = 'mongodb://{}:{}@{}/{}'.format(USERNAME,PASSWORD,SERVER_NAME,DATABASE_NAME)
mongoClient = MongoClient(uri)
collection = mongoClient[DATABASE_NAME][COLLECTION_NAME]
cursor = collection.find(QUERY)
print cursor.count()

pymongo 版本是 3.4。

【问题讨论】:

    标签: python mongodb python-2.7 mongodb-query


    【解决方案1】:

    您可以使用聚合框架,它提供$strLenCP 来获取字符串的长度,并提供$cmp 来比较它们:

    db.collection.aggregate(
      [
        {
          $match: {
            "x" : {'$gt' : 1.0},
            "y" : {'$gt' : 0.1}
          }
        },
        {
          $addFields: {
            str_cmp: { $cmp: [ { $strLenCP: "$s1" }, { $add: [ { $strLenCP: "$s2" }, 3 ] } ] }
          }
        },
        {
          $match: {
            "str_cmp": -1,
          }
        }
      ]
    )
    

    【讨论】:

    • 这会向数据库中插入新数据吗?
    • 为什么?你需要获取还是插入?
    • 顺便说一句,正如您在我的查询中看到的那样,我正在尝试汇总 s1 的长度小于 s2 + 3 的长度的情况。如何调整您的解决方案?
    • 我不需要插入,我只是想确保您的解决方案不需要,因为我不确定 $addFields 运算符的作用,并且听起来像插入。
    • 啊,错过了+3的东西。看我的更新。它将str_cmp 字段添加到结果中,但不会修改静态数据。您可以忽略多余的字段,也可以添加另一个投影阶段将其删除。
    猜你喜欢
    • 2021-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-25
    • 2020-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多