python - Pymongo中根据值长度查询集合和文档

标签 python mongodb mongodb-query pymongo pymongo-3.x

假设我的数据库给我一个查询结果:

{'_id': ObjectId('5c99d76a32aacf180485c3b3'),
 'text': 'ILLUSTRATION : 1\nFind the quotient and remainder q and r for the pairs of positive integers given below:\n(i) 23,4\n(ii) 81,3\n(iii) 12,5\nUTION.\n',
 'text2': '',
 'parent': None,
 'repost': 3,
 'time': datetime.datetime(2010, 5, 9, 16, 5, 27, 838000)}

我想获取前 1000 个文档,其中 text 的长度或 text2 的长度 >=5:

我可以通过 Python 做到这一点,但这样做是愚蠢的:

objects = []
i = 0
for obj in db.essays.find():
    if len(obj['text']>=5) or len(obj['text2']>=5):
        objects.append(obj)
        i+=1
    if i==1000:
        break

我知道这很愚蠢。

如果我有完全匹配,我可以使用 limit(1000) 但我不知道如何根据值长度获取文档。

编辑: 我设法以某种方式做了一个PATCH:

{ "$or":[{"$expr": { "$gt": [ { "$strLenCP": "$text" }, 5 ]}},
                                     {"$expr": { "$gt": [ { "$strLenCP": "$text2" }, 5 ]}},
                                    {"$expr": { "$gt": [ { "$strLenCP": "$text3" }, 5 ]}},
                                     ]}

但是当我使用 AND 操作获取文档时,当所有文本的长度都小于 3 时,它会抛出错误:

{ "$and":[{"$expr": { "$lt": [ { "$strLenCP": "$text" }, 5 ]}},
                                     {"$expr": { "$lt": [ { "$strLenCP": "$text2" }, 5 ]}},
                                    {"$expr": { "$lt": [ { "$strLenCP": "$text3" }, 5 ]}},
                                     ]}

它适用于 limit(2) 但因 >2 而失败并抛出错误:

`OperationFailure: $strLenCP requires a string argument, found: null`

最佳答案

您可以将管道与 strLenCP 一起使用

db.collection.aggregate([
  {
    "$match": {
      "$expr": {
        "$or": [
          {
            "$gte": [
              {
                "$strLenCP": {
                  "$ifNull": [
                    "$text",
                    ""
                  ]
                }
              },
              5
            ]
          },
          {
            "$gte": [
              {
                "$strLenCP": {
                  "$ifNull": [
                    "$text2",
                    ""
                  ]
                }
              },
              5
            ]
          }
        ]
      }
    }
  },
  {
    "$limit": 1000
  }
])

但是,如果您真的关心性能之上的问题,最好的方法是预处理该信息:

{
'_id': ObjectId('5c99d76a32aacf180485c3b3'),
 'text': 'ILLUSTRATION : 1\nFind the quotient and remainder q and r for the pairs of positive integers given below:\n(i) 23,4\n(ii) 81,3\n(iii) 12,5\nUTION.\n',
 'text2': '',
 'parent': None,
 'repost': 3,
 'time': datetime.datetime(2010, 5, 9, 16, 5, 27, 838000),
  'text_len': 100,
  "text2_len": 0
}

所以现在一个简单的查询就足够了:

db.essays.find({"$or": [{"text_len": {"$gte": 5}}, {"text2_len": {"$gte": 5}}]}).limit(1000)

Mongo Playground

关于python - Pymongo中根据值长度查询集合和文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62816718/

相关文章:

python - 是什么改变了这个 pandas 代码中的日期类型?

python - Ansible - 如何在 SSH session 中设置 ansible_env.PATH

node.js - 如何在 ExpressJS 和 multer 中将数据从一个路由器传递到另一个路由器?

javascript - Mongoose Node Js 连接两个集合

node.js - 如何在mongodb中过滤两次之间的数据

mongodb - MongoConnectionTimeOut 无法使用 MongoClientURI

python - 2-opt 算法解决 Python 中的旅行商问题

python - 如何测试 Python 函数是否引发异常?

python - 使用 pymongo 从/向磁盘加载和保存 mongoDB 数据库

mongodb - 根据 MongoDB 中的属性更新嵌套数组对象