Chúng tôi có thể trực tiếp lọc trên tài liệu có các trường ReferenceField's
trong một truy vấn không?
Không, của nó không thể trực tiếp lọc một tài liệu với các lĩnh vực ReferenceField
như làm điều này sẽ đòi hỏi tham gia và MongoDB không hỗ trợ tham gia.
Theo tài liệu MongoDB trên database references:
MongoDB không hỗ trợ tham gia. Trong MongoDB, một số dữ liệu không được chuẩn hóa, hoặc được lưu trữ với dữ liệu liên quan trong tài liệu để loại bỏ nhu cầu tham gia.
Từ page khác trên trang web chính thức:
Nếu chúng ta đang sử dụng một cơ sở dữ liệu quan hệ, chúng ta có thể thực hiện liên kết người sử dụng và các cửa hàng, và nhận được tất cả đối tượng của chúng tôi trong một truy vấn duy nhất. Nhưng MongoDB không hỗ trợ kết nối và đôi khi, yêu cầu bit không chuẩn hóa.
Người theo chủ nghĩa thuần túy quan hệ có thể cảm thấy không thoải mái, như thể chúng tôi là vi phạm một số luật phổ quát. Nhưng hãy nhớ rằng các bộ sưu tập MongoDB không tương đương với các bảng quan hệ; mỗi mục tiêu một mục tiêu thiết kế độc đáo là . Bảng được chuẩn hóa cung cấp một đoạn dữ liệu riêng lẻ, . Tuy nhiên, một tài liệu, đại diện chặt chẽ hơn đối với một đối tượng nói chung là .
Vì vậy, trong 1 truy vấn, chúng tôi không thể đồng thời lọc tasks
với một giá trị cờ nói riêng và với trao user_id
và task_id
trên mô hình UserTasks
.
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 các mô hình Tasks
với trao task_id
và flag
. Sau đó, trong truy vấn thứ 2, chúng tôi sẽ lọc mô hình UserTasks
với số user_id
và task
đã nhận được từ truy vấn đầu tiên.
Ví dụ:
phép nói rằng chúng tôi có một user_id
, task_id
và chúng ta cần phải kiểm tra xem các nhiệm vụ liên quan có giá trị flag
như 0
.
1 Query
Đầu tiên chúng ta sẽ truy xuất các my_task
với trao task_id
và flag
như 0
.
my_task = Tasks.objects.get(task_id=task_id, flag=0) # 1st query
2 Query
Sau đó, trong truy vấn thứ 2, bạn cần phải lọc trên UserTask
mô hình với trao user_id
và my_task
đối tượng.
my_user_task = UserTasks.objects.get(user_id=user_id, tasks=my_task) # 2nd query
Bạn nên thực hiện truy vấn thứ 2 chỉ nếu bạn nhận được một đối tượng my_task
với trao task_id
và flag
giá trị. Ngoài ra, bạn sẽ cần phải thêm xử lý lỗi trong trường hợp không có đối tượng phù hợp.
Nếu chúng ta đã sử dụng EmbeddedDocument
cho kiểu Tasks
thì sao?
phép nói rằng chúng tôi đã xác định tài liệu Tasks
của chúng tôi như một EmbeddedDocument
và tasks
trường trong UserTasks
mô hình như một EmbeddedDocumentField
, sau đó làm việc lọc mong muốn chúng ta có thể làm một cái gì đó như dưới đây:
my_user_task = UserTasks.objects.get(user_id=user_id, tasks__task_id=task_id, tasks__flag=0)
Bắt cụ thể my_task
từ danh sách nhiệm vụ
Truy vấn trên sẽ trả về tài liệu UserTask
ntain 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 nhiệm vụ mong muốn.
Để thực hiện đ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ử thứ nhất 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]
Phiên bản mongoengine và pymongo bạn đang sử dụng? –
'pymongo == 3.0.3' và' mongoengine == 0.10.0' – PythonEnthusiast