Order_by mongoengine 中列表字段的长度
Order_by length of listfield in mongoengine
我不想 运行 查询获取所有超过 6 com
的文章,然后根据 com
列表的长度排序,
为此,我这样做了:
ArticleModel.objects.filter(com__6__exists=True).order_by('-com.length')[:50]
假设 com 是一个 ListField,但无法进行排序,我该如何解决?谢谢
标准查询无法执行此操作,因为 "sort" 需要在文档中存在的物理字段上执行。执行此操作的最佳方法是实际将 "list" 计数作为文档中的另一个字段。这也使您的查询更有效率,并且 "counter" 字段可以被索引,因此基本查询变为 ( Raw MongoDB sytax ) :
{ "comLength": { "$gt": 6 } }
如果您不能或不想更改文档结构,那么按列表长度排序的唯一方法是 $project
it via .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
aggregation operator. If you don't then you have to $unwind
and $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()
中的聚合提供程序实际上可以 "create a field" 文档中不存在的内容。也没有测试可用于标准投影或文档排序的 "current" 长度。
添加另一个字段并使其与实际数组长度保持同步的最佳选择。但如果失败,上面会向您展示一般方法。
如果您正在创建数据库并且您知道此类请求通常会被大量请求,建议在 A ArticleModel
中添加“com_length”字段并使其在每次保存时自动插入使用 save()
方法
在 models.py
中添加 ArticleModel
def save(self, *args, **kwargs):
self.com_length = len(self.com)
return super(ArticleModel, self).save(*args, **kwargs)
然后请求提出的问题:
ArticleModel.objects.filter(com__6__exists=True).order_by('-com_length')[:50]
我不想 运行 查询获取所有超过 6 com
的文章,然后根据 com
列表的长度排序,
为此,我这样做了:
ArticleModel.objects.filter(com__6__exists=True).order_by('-com.length')[:50]
假设 com 是一个 ListField,但无法进行排序,我该如何解决?谢谢
标准查询无法执行此操作,因为 "sort" 需要在文档中存在的物理字段上执行。执行此操作的最佳方法是实际将 "list" 计数作为文档中的另一个字段。这也使您的查询更有效率,并且 "counter" 字段可以被索引,因此基本查询变为 ( Raw MongoDB sytax ) :
{ "comLength": { "$gt": 6 } }
如果您不能或不想更改文档结构,那么按列表长度排序的唯一方法是 $project
it via .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
aggregation operator. If you don't then you have to $unwind
and $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()
中的聚合提供程序实际上可以 "create a field" 文档中不存在的内容。也没有测试可用于标准投影或文档排序的 "current" 长度。
添加另一个字段并使其与实际数组长度保持同步的最佳选择。但如果失败,上面会向您展示一般方法。
如果您正在创建数据库并且您知道此类请求通常会被大量请求,建议在 A ArticleModel
中添加“com_length”字段并使其在每次保存时自动插入使用 save()
方法
在 models.py
中添加ArticleModel
def save(self, *args, **kwargs):
self.com_length = len(self.com)
return super(ArticleModel, self).save(*args, **kwargs)
然后请求提出的问题:
ArticleModel.objects.filter(com__6__exists=True).order_by('-com_length')[:50]