mongodb - order_by mongoengine中listfield的长度

标签 mongodb python-2.7 mongodb-query aggregation-framework mongoengine

我不想运行查询来获取所有超过 6 个 com 的文章,然后根据 com 列表的长度进行排序, 为此,我这样做了:

 ArticleModel.objects.filter(com__6__exists=True).order_by('-com.length')[:50]                                                                  

假设 com 是一个 ListField,但排序不起作用,我该如何解决?谢谢

最佳答案

标准查询不能这样做,因为“排序”需要在文档中存在的物理字段上完成。执行此操作的最佳方法是实际将您的“列表”计数作为文档中的另一个字段。这也使您的查询更有效率,并且可以为“计数器”字段编制索引,因此基本查询变为(原始 MongoDB sytax):

{ "comLength": { "$gt": 6 } }

如果您不能或不想更改文档结构,那么按列表长度排序的唯一方法是 $project它通过 .aggregate() :

ArticleModel._get_collection().aggregate([
    { "$match": { "com.6": { "$exists": true } }},
    { "$project": {
        "com": 1,
        "otherField": 1,
        "comLength": { "$size": "$com" }
    }},
    { "$sort": { "comLength": -1 } }
])

并且考虑到您至少拥有 MongoDB 2.6 才能使用 $size聚合运算符。如果你不这样做,那么你必须 $unwind$group为了计算数组的长度:

ArticleModel._get_collection().aggregate([
    { "$match": { "com.6": { "$exists": true } }},
    { "$unwind": "$com" },
    { "$group": {
        "_id": "$_id",
        "otherField": { "$first": "$otherField" }
        "com": { "$push": "$com" },
        "comLength": { "$sum": 1 }
    }},
    { "$sort": { "comLength": -1 } }
])

因此,如果您要走那条路,那么请仔细阅读文档,因为您可能不习惯原始的 MongoDB 语法并且一直在使用 MongoEngine 提供的查询 DSL。

总的来说,只有 .aggregate().mapReduce() 中的聚合提供程序才能实际“创建文档中不存在的字段”。也没有测试可用于标准投影或文档排序的“当前”长度。

添加另一个字段并使其与实际数组长度保持同步的最佳选择。但如果失败,上面会向您展示一般方法。

关于mongodb - order_by mongoengine中listfield的长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28950366/

相关文章:

python - 我如何使用字典理解来计算文档中每个单词的出现次数

python - 使用新格式字符串记录变量数据

mongodb - 查找并删除所有 "createdDate"早一个月的文档

javascript - 简单的 Node api请求不显示任何数据

mongodb - 使用 MongoDB 有效地确定层次结构中记录的所有者

arrays - 使用 $addToSet Mongo 运算符添加多个值

C# 连接并查询现有的 MongoDb

mysql - 将 mysql 数据库中的图像(BLOB)显示到 tkinter 窗口

node.js - 需要比较mongodb中2个不同的日期字段

mongodb - 我可以转换 MongoDB 文档以在数组中包含一个数组吗?