2013-04-11 45 views
1

我看过this question,但它不能回答我的问题,甚至无法很好地解决问题。Mongoengine - 全部使用icontains

我认为这是最好的一个例子来解释:

class Blah(Document): 
    someList = ListField(StringField()) 

Blah.drop_collection() 

Blah(someList=['lop', 'glob', 'hat']).save() 
Blah(someList=['hello', 'kitty']).save() 

# One of these should match the first entry 
print(Blah.objects(someList__icontains__all=['Lo']).count()) 
print(Blah.objects(someList__all__icontains=['Lo']).count()) 

我假定这将打印要么1, 00, 1(或奇迹般地1, 1),而是它给

0 
Traceback (most recent call last): 
    File "metst.py", line 14, in <module> 
    print(Blah.objects(someList__all__icontains=['lO']).count()) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 1034, in count 
    return self._cursor.count(with_limit_and_skip=True) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 608, in _cursor 
    self._cursor_obj = self._collection.find(self._query, 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 390, in _query 
    self._mongo_query = self._query_obj.to_query(self._document) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 213, in to_query 
    query = query.accept(QueryCompilerVisitor(document)) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 278, in accept 
    return visitor.visit_query(self) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 170, in visit_query 
    return QuerySet._transform_query(self.document, **query.query) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/queryset.py", line 755, in _transform_query 
    value = field.prepare_query_value(op, value) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/fields.py", line 594, in prepare_query_value 
    return self.field.prepare_query_value(op, value) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/site-packages/mongoengine/fields.py", line 95, in prepare_query_value 
    value = re.escape(value) 
    File "/home/blah/.pythonbrew/pythons/Python-3.1.4/lib/python3.1/re.py", line 246, in escape 
    return bytes(s) 
TypeError: 'str' object cannot be interpreted as an integer 

无论查询作品!

MongoEngine是否支持某种方式使用icontainsall进行搜索?或者以某种方式解决这个问题?

注意:我想使用MongoEngine,而不是PyMongo。

编辑:Python 2.7.3存在同样的问题。

+0

如果你做了一个原始查询,比如'Blah.objects(__ raw __ = {“someList”:{“$ all”:[“/ 10/i”]}})。count()'? – alecxe 2013-04-21 21:38:09

+0

使用它返回计数的“0”,就像我描述的第一个打印选项。 – William 2013-04-22 13:32:35

+0

对不起,我用'0'代替'O',试试这个:'Blah.objects(__ raw __ = {“someList”:{“$ all”:[“/ 1O/i”]}} ).Count之间()'。 – alecxe 2013-04-22 13:36:55

回答

1

截至目前(版本0.8.0)的唯一方法是使用__raw__查询,可能与re.compile()结合使用。像这样:

import re 

input_list = ['Lo'] 
converted_list = [re.compile(q, re.I) for q in input_list] 

print(Blah.objects(__raw__={"someList": {"$all": converted_list}}).count()) 

目前在mongoengine没有办法结合allicontains,并且可以与其他运营商使用的唯一操作员not。这是微妙the docs提到的那样,在它说:

不 - 否定标准检查,可以其他运营商之前使用(例如Q(age_ _mod = 5))

重点煤矿

但它并没有说你不能与其他运营商做到这一点,这实际上是将案件。


您可以通过查看源确认此行为:

版本0.8.0+(in module - mongoengine/queryset/transform.py - 线42-48):

if parts[-1] in MATCH_OPERATORS: 
    op = parts.pop() 

negate = False 
if parts[-1] == 'not': 
    parts.pop() 
    negate = True 

在旧版本上线可见mongoengine/queryset.py内的_transform_query方法。