具有以列表中指定的前缀开头的属性的对象的MongoEngine查询列表

时间:2012-04-27 10:19:47

标签: python mongodb mongoengine nosql

我需要在Mongo数据库中查询具有以列表中任何前缀开头的特定属性的元素。现在我有一段这样的代码:

query = mymodel(terms__term__in=query_terms)

并且匹配列表“terms”上具有项目的对象,该列表具有明确出现在列表“query_terms”上的StringField“term”。我想要实现的是让对象在列表“条款”上有一个项目,其中StringField“term”以列表“query_terms”上出现的任何前缀开头。是否可以在一个查询中执行此操作而不在数据库中存储每个可能的“term”前缀? 编辑: 下面的解决方案效果很好但现在我必须找到条目以列表中的每个前缀开头的对象。我改变了

query = reduce(lambda q1, q2: q1.__or__(q2), 
           map(lambda prefix: Q(terms__term__startswith=prefix)))

query = reduce(lambda q1, q2: q1.__and__(q2), 
           map(lambda prefix: Q(terms__term__startswith=prefix)))

但这不起作用。我最终收到以下错误:

InvalidQueryError: Duplicate query conditions: terms__term__startswith

有什么想法吗?

2 个答案:

答案 0 :(得分:9)

如果你查询一个术语的值,你可以过滤那些以perfix开头的值,如下所示:

MyModel.objects.filter(terms__term__startswith='foo')

如果您需要过滤多个前缀,则必须为此创建Q对象:

MyModel.objects.filter(Q(terms__term__startswith='foo') | Q(terms__term__startswith='bar'))

如果您需要动态创建查询:

prefixes = ['foo', 'bar', 'baz']
query = reduce(lambda q1, q2: q1.__or__(q2), 
               map(lambda prefix: Q(terms__term__startswith=prefix), prefixes))
MyModel.objects.filter(query)

答案 1 :(得分:2)

您可以使用^(prefix1 | prefix2 etc)之类的正则表达式:

prefixes = [....]
regex = '^(%s)' % '|'.join(map(re.escape, prefixes))
docs = your_collection.find({'term': {'$regex': regex}})
升:没有注意到这个问题是关于mongoengine的。以上是纯pymongo,不知道ME是否允许这样做。