Chúng tôi có thể lọc trực tiếp trên một tài liệu bằng ReferenceField's
các trường trong một truy vấn?
Không, không thể lọc trực tiếp tài liệu với các trường của ReferenceField
vì làm điều này sẽ yêu cầu tham gia và mongodb không hỗ trợ tham gia.
Theo tài liệu MongoDB trên tham chiếu cơ sở dữ liệu:
Từ một trang khác trên trang web chính thức:
Vì vậy, trong 1 truy vấn, chúng tôi không thể lọc cả tasks
với một giá trị cờ cụ thể và với user_id
đã cho và task_id
trên UserTasks
mô hình.
Sau đó làm cách nào để thực hiện lọc?
Để thực hiện lọc theo các điều kiện bắt buộc, chúng tôi sẽ cần thực hiện 2 truy vấn.
Trong truy vấn đầu tiên, chúng tôi sẽ cố gắng lọc Tasks
mô hình với task_id
đã cho và flag
. Sau đó, trong truy vấn thứ 2, chúng tôi sẽ lọc UserTasks
mô hình với user_id
đã cho và tasks
được truy xuất từ truy vấn đầu tiên.
Ví dụ:
Giả sử chúng ta có user_id
, task_id
và chúng ta cần kiểm tra xem tác vụ liên quan có cờ flag
không giá trị là 0
.
Truy vấn đầu tiên
Trước tiên, chúng tôi sẽ truy xuất lại my_task
với task_id
đã cho và flag
dưới dạng 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
Truy vấn thứ 2
Sau đó, trong truy vấn thứ 2, bạn cần lọc trên UserTask
mô hình với user_id
đã cho và my_task
đối tượng.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Bạn chỉ nên thực hiện truy vấn thứ 2 nếu bạn nhận được my_task
đối tượng với task_id
đã cho và flag
giá trị. Ngoài ra, bạn sẽ cần thêm xử lý lỗi trong trường hợp không có đối tượng phù hợp.
Điều gì sẽ xảy ra nếu chúng tôi đã sử dụng EmbeddedDocument
cho Tasks
mô hình?
Giả sử chúng tôi đã xác định Tasks
của mình tài liệu dưới dạng EmbeddedDocument
và tasks
trong UserTasks
mô hình dưới dạng EmbeddedDocumentField
, sau đó để thực hiện lọc mong muốn, chúng tôi có thể thực hiện một số việc như sau:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Lấy my_task
cụ thể từ danh sách nhiệm vụ
Truy vấn trên sẽ trả về một UserTask
tài liệu sẽ chứa tất cả các tasks
. Sau đó, chúng tôi sẽ cần thực hiện một số loại lặp lại để có được tác vụ mong muốn.
Để làm điều đó, chúng tôi có thể thực hiện việc hiểu danh sách bằng cách sử dụng enumerate()
Sau đó chỉ mục mong muốn sẽ là phần tử đầu tiên của danh sách 1 phần tử được trả về.
my_task_index = [i for i,v in enumerate(my_user_task.tasks) if v.flag==0][0]