2012-04-27 25 views
6

Tôi cần truy vấn cơ sở dữ liệu Mongo cho các phần tử có thuộc tính nhất định bắt đầu bằng bất kỳ tiền tố nào trong danh sách. Bây giờ tôi có một đoạn mã như thế này:Danh sách truy vấn MongoEngine cho các đối tượng có thuộc tính bắt đầu bằng tiền tố được chỉ định trong danh sách

query = mymodel(terms__term__in=query_terms) 

và điều này phù hợp với đối tượng mà có một mục trong danh sách "thuật ngữ" có Stringfield "hạn" một cách rõ ràng xảy ra trên một danh sách "QUERY_TERMS". Những gì tôi muốn đạt được là có các đối tượng có một mục trong danh sách "các thuật ngữ" có StringField "thuật ngữ" bắt đầu với bất kỳ tiền tố nào xuất hiện trong danh sách "query_terms". Có thể làm điều đó trong một truy vấn và không lưu trữ mọi tiền tố có thể có của "thuật ngữ" trong cơ sở dữ liệu? EDIT: Giải pháp bên dưới hoạt động tốt nhưng bây giờ tôi phải tìm các đối tượng có thuật ngữ bắt đầu bằng mọi tiền tố trên danh sách. Tôi đã thay đổi

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))) 

nhưng điều này không hoạt động. Tôi sẽ gặp phải lỗi sau:

Bất kỳ ý tưởng nào?

Trả lời

9

Nếu bạn truy vấn một thuật ngữ cho giá trị của nó, bạn có thể lọc các giá trị mà bắt đầu với một perfix như vậy:

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

Nếu bạn cần phải lọc cho nhiều tiền tố bạn sẽ phải tạo các đối tượng Q cho rằng:

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

Nếu bạn cần để tạo ra các truy vấn tự động:

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) 
+0

Cảm ơn, nó dễ dàng hơn tôi nghĩ và hoạt động tuyệt vời! –

+0

Xin cảm ơn @min Tôi đã thêm chỉnh sửa của bạn. –

2

Bạn có thể sử dụng một biểu thức chính quy như ^(prefix1 | prefix2 etc):

prefixes = [....] 
regex = '^(%s)' % '|'.join(map(re.escape, prefixes)) 
docs = your_collection.find({'term': {'$regex': regex}}) 

UPD: không để ý câu hỏi này là về mongoengine. Ở trên là cho pymongo tinh khiết, không biết nếu ME cho phép điều này.

Các vấn đề liên quan