2012-04-27 13 views
6

Necesito consultar en la base de datos de Mongo los elementos que tienen una propiedad determinada que comienza con cualquier prefijo en la lista. Ahora tengo un pedazo de código como este:Lista de consultas de Mongo Engine para objetos que tienen propiedades que comienzan con prefijos especificados en una lista

query = mymodel(terms__term__in=query_terms) 

y esto coincide con objetos que tienen un elemento en una lista de "términos" que tiene Stringfield "término" que ocurre explícitamente en una lista de "QUERY_TERMS". Lo que quiero lograr es tener objetos que tengan un elemento en una lista de "términos" que tenga "término" StringField que comience con cualquier prefijo que aparezca en una lista "query_terms". ¿Es posible hacerlo en una consulta y sin almacenar todos los prefijos posibles de "término" en la base de datos? EDITAR: La siguiente solución funciona muy bien, pero ahora tengo que encontrar objetos con términos que comiencen con cada prefijo en una lista. He cambiado

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

a

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

pero esto no funciona. Termino obteniendo el siguiente error:

¿Alguna idea?

Respuesta

9

Si su consulta de un término por su valor, puede filtrar los valores que comiencen con un PERFIX así:

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

Si necesita filtrar para varios prefijos que tendrá que crear objetos Q de que:

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

Si usted necesita para crear la consulta de forma dinámica:

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

Gracias, es más fácil de lo que pensaba y ¡Funciona genial! –

+0

Gracias @min He agregado su edición. –

2

Se puede utilizar una expresión regular como ^(prefix1 | prefix2 etc):

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

UPD: no se dio cuenta esta pregunta es sobre mongoengine. Lo anterior es para pymongo puro, no sé si ME lo permite.

Cuestiones relacionadas