mongoengine - 查询如何按ListField大小过滤

rat*_*rat 10 python mongodb mongoengine mongodb-query

我有以下型号:

class Like(EmbeddedDocument):
    user = ReferenceField(User,dbref=False)
    date = DateTimeField(default=datetime.utcnow,required=True)
    meta = {'allow_inheritance': False}

class Post(Document):
   name = StringField(max_length=120, required=True)
   likes = ListField(EmbeddedDocumentField(Like))
Run Code Online (Sandbox Code Playgroud)

我想只过滤超过20个喜欢的帖子(ListField大小超过20).我试过查询使用:

posts = Post.objects.filter(likes__size_gte=20)
posts = Post.objects.filter(likes_gte=20)
posts = Post.objects.filter(likes__gte=20)
posts = Post.objects.filter(likes__size_gte=20)
Run Code Online (Sandbox Code Playgroud)

他们都没有工作.

但如果我使用完全匹配(ListField大小正好20个喜欢)它的工作原理:

posts = Post.objects.filter(likes__size=20) 
Run Code Online (Sandbox Code Playgroud)

评论?

ypr*_*rez 14

远非完美的解决方案,但您可以使用原始mongo查询和$ where运算符,例如:

posts = Post.objects.filter(__raw__={'$where': 'this.likes.length > 20'})
Run Code Online (Sandbox Code Playgroud)

另一种选择,它应该更快,但在我看来不太清楚,是检查第21个元素是否存在:

posts = Post.objects.filter(likes__21__exists=True)
Run Code Online (Sandbox Code Playgroud)

第二个选项仅在您使用MongoDB 2.2+时才有效

来源:取自这些答案并应用于MongoEngine.


egr*_*ene 5

您不能将 $size 用于一系列值。

来自蒙戈的网站:

$size 不接受值范围。要根据具有不同元素数量的字段选择文档,请创建一个计数器字段,在向字段添加元素时该计数器字段会递增。

这是导致答案的相关问题的链接:在 mongoDB 中删除数组字段大小小于 3 的文档

这是上一个链接链接到的 mongo 页面,该页面提供了上面块中的文档: http ://docs.mongodb.org/manual/reference/operator/size/#_S_size

尝试按照文本块中的建议添加计数器字段。