2012-04-27 5 views
6

Potrzebuję do zapytania bazy danych Mongo dla elementów, które mają określoną właściwość zaczynającą się od dowolnego prefiksu na liście. Teraz mam kawałek kodu:Lista zapytań MongoEngine dla obiektów mających właściwości zaczynające się od prefiksów określonych na liście

query = mymodel(terms__term__in=query_terms) 

i ten pasuje do przedmiotów, które mają pozycję na liście „warunki”, które Stringfield „termin” wyraźnie występujące na liście „QUERY_TERMS”. Co chcę osiągnąć, to posiadanie obiektów, które mają pozycję na liście "warunki", która ma "termin" StringField zaczynający się od dowolnego przedrostka, który występuje na liście "query_terms". Czy można to zrobić w jednym zapytaniu i bez zapisywania każdego możliwego prefiksu "terminu" w bazie danych? EDYTOWANIE: Rozwiązanie poniżej działa świetnie, ale teraz muszę znaleźć obiekty z terminami zaczynającymi się od każdego prefiksu na liście. Zmieniłem

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

do

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

ale to nie działa. W efekcie otrzymuję następujący błąd:

Jakieś pomysły?

Odpowiedz

9

Jeśli Twój zapytań termin na jego wartość, można filtrować poszczególne wartości, które zaczynają się perfix tak:

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

Jeśli trzeba filtrować wielu prefiksów musisz tworzyć obiekty q że:

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

Jeśli trzeba utworzyć kwerendę dynamicznie:

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

Dzięki, jest to łatwiejsze niż myślałem i działa świetnie! –

+0

Dzięki @min Dodałem Twoją edycję. –

2

Można użyć wyrażenia regularnego jak ^(prefix1 | prefix2 etc):

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

UPD: nie zauważył to pytanie jest o mongoengine. Powyższe jest dla czystego pymongo, nie wiem, czy MNIE pozwala na to.

Powiązane problemy