sql >> Base de Datos >  >> NoSQL >> MongoDB

Consulta de documentos incrustados de Mongo

¿Podemos filtrar directamente en un documento con ReferenceField's campos en una sola consulta?

No, no es posible filtrar directamente un documento con los campos de ReferenceField ya que hacer esto requeriría uniones y mongodb no admite uniones.

Según los documentos de MongoDB en referencias de bases de datos:

De otra página en el sitio oficial:

Entonces, en 1 consulta, no podemos filtrar tasks con un valor de bandera particular y con el user_id dado y task_id en UserTasks modelo.

¿Cómo realizar el filtrado entonces?

Para realizar el filtrado según las condiciones requeridas, necesitaremos realizar 2 consultas.

En la primera consulta intentaremos filtrar las Tasks modelo con el task_id dado y flag . Luego, en la segunda consulta, filtraremos UserTasks modelo con el user_id dado y la task recuperado de la primera consulta.

Ejemplo:

Digamos que tenemos un user_id , task_id y necesitamos verificar si la tarea relacionada tiene flag valor como 0 .

1ra Consulta

Primero recuperaremos el my_task con el task_id dado y flag como 0 .

my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query

Segunda consulta

Luego, en la segunda consulta, debe filtrar en UserTask modelo con el user_id dado y my_task objeto.

my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query

Debe realizar la segunda consulta solo si obtiene un my_task objeto con el task_id dado y flag valor. Además, deberá agregar el manejo de errores en caso de que no haya objetos coincidentes.

¿Qué pasa si hemos usado EmbeddedDocument? para las Tasks modelo?

Digamos que hemos definido nuestras Tasks documento como un EmbeddedDocument y las tasks campo en UserTasks modelo como un EmbeddedDocumentField , luego, para hacer el filtrado deseado, podríamos haber hecho algo como lo siguiente:

my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)

Obteniendo my_task en particular de la lista de tareas

La consulta anterior devolverá una UserTask documento que contendrá todas las tasks . Entonces tendremos que realizar algún tipo de iteración para obtener la tarea deseada.

Para hacer eso, podemos realizar la comprensión de la lista usando enumerate() .Entonces el índice deseado será el primer elemento de la lista de 1 elemento devuelta.

my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]