Làm cách nào để khớp một mảng đối tượng trong tổng hợp mongodb?

Trong bài viết "Mẹo nhanh" này, chúng tôi xem xét cách chỉ truy xuất phần tử được truy vấn trong một đối tượng mảng trong MongoDB

Một kịch bản điển hình cho cơ sở dữ liệu NoSQL dựa trên tài liệu là lưu trữ các tài liệu có chứa một mảng các đối tượng, chẳng hạn như các đối tượng này

{
"name": "John",
"cars": [{
"make": "Ford",
"colour": "red"
}, {
"make": "Mercedes",
"colour": "blue"
}]
}
{
"name": "Susan",
"cars": [{
"make": "Fiat",
"colour": "red"
}, {
"make": "BMW",
"colour": "black"
}]
}

Thường thì điều trên được gọi là không chuẩn hóa vì chúng tôi đặt mọi thứ chúng tôi biết về một thực thể dữ liệu nhất định vào một đối tượng tài liệu

Mỗi người có một tài sản cars, là một loạt các đối tượng xe hơi, mỗi người có một tài sản make và một tài sản colour

Bây giờ, điều gì sẽ xảy ra nếu chúng ta muốn thực hiện một truy vấn và trả về các tài liệu phù hợp trong đó màu của ô tô là "xanh dương". Bằng cách chạy truy vấn find() tiêu chuẩn, chúng tôi nhận được toàn bộ tài liệu với tất cả các mục mảng được trả về

db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}

Cập nhật truy vấn trước đó để bao gồm phép chiếu, chúng tôi vẫn nhận được cả hai đối tượng thay vì chỉ có "chiếc xe màu xanh" mà chúng tôi đang tìm kiếm

db.people.find({ 'cars.colour': 'blue' }, { 'cars.colour': 1 }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"cars" : [
{
"colour" : "red"
},
{
"colour" : "blue"
}
]
}

Điều này có thể hiệu quả đối với một số tình huống nhất định;

Để đạt được điều này, chúng ta cần giới thiệu và sử dụng MongoDB's Aggregation. Hãy nghĩ về tập hợp này như một đường dẫn trong đó các tài liệu trải qua nhiều giai đoạn chuyển đổi - bao gồm nhóm các giá trị lại với nhau, thêm các trường được tính toán hoặc thậm chí tạo các đối tượng phụ ảo

Hãy xem cách truy vấn tổng hợp sẽ như thế nào

db.people.aggregate([
{ $match: { 'cars.colour': 'blue' } },
{
$project: {
cars: {
$filter: {
input: '$cars',
as: 'cars',
cond: { $eq: ['$$cars.colour', 'blue'] },
},
},
_id: 0,
},
},
]);

Phần đầu tiên với

db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
0 rất đơn giản giống như phần chúng tôi đã làm trước đây - chúng tôi khớp các tài liệu có màu ô tô là "xanh dương". Sau
db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
0, chúng tôi sử dụng
db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
2 cho phép chúng tôi cùng với các trường cụ thể (hiện có hoặc được tính toán). Về cơ bản, chúng tôi xây dựng lại thuộc tính cars, với một điều kiện nhất định như được chỉ định bởi thuộc tính
db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
3 cho
db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
4 - chúng tôi chỉ muốn xem những chiếc ô tô có màu xanh lam và bây giờ chúng tôi đang tham chiếu đầu vào cho tổng hợp của mình (cũng như trường
db.people.find({ 'cars.colour': 'blue' }).pretty();
{
"_id" : ObjectId("5c4ab3bf996018528b1ef283"),
"name" : "John",
"cars" : [
{
"make" : "Ford",
"colour" : "red"
},
{
"make" : "Mercedes",
"colour" : "blue"
}
]
}
5 . Kết quả sẽ chính xác như những gì chúng ta đang theo đuổi

{ "cars": [{ "make": "Mercedes", "colour": "blue" }] }

Và nếu bạn đang thắc mắc, làm thế nào để sử dụng cái này từ một Node. js (hoặc từ bất kỳ SDK MongoDB nào khác cho vấn đề đó), đừng lo lắng, nó không thể đơn giản hơn. Tất cả những gì chúng ta cần là lấy truy vấn đã thấy trước đó và thêm vào Node. js theo cách sau

Làm cách nào để khớp các phần tử mảng trong MongoDB?

Toán tử $elemMatch khớp với các tài liệu chứa trường mảng có ít nhất một phần tử khớp với tất cả các tiêu chí truy vấn đã chỉ định. Nếu bạn chỉ xác định một điều kiện

Làm cách nào để kiểm tra xem mảng có chứa giá trị trong MongoDB không?

Để truy vấn xem trường mảng có chứa ít nhất một phần tử có giá trị được chỉ định hay không, hãy sử dụng bộ lọc { . Để chỉ định điều kiện cho các phần tử trong trường mảng, hãy sử dụng các toán tử truy vấn trong tài liệu bộ lọc truy vấn. {

Làm cách nào để cập nhật mảng đối tượng trong MongoDB?

Để thực hiện cập nhật trên tất cả các phần tử mảng nhúng của từng tài liệu phù hợp với truy vấn của bạn, hãy sử dụng toán tử vị trí đã lọc $[ ] chỉ định các phần tử mảng phù hợp trong tài liệu cập nhật.

Giai đoạn tổng hợp $match có thể được sử dụng để làm gì?

Giai đoạn tổng hợp này hoạt động giống như một tìm kiếm. Nó sẽ lọc tài liệu phù hợp với truy vấn được cung cấp . Sử dụng $match sớm trong quy trình có thể cải thiện hiệu suất vì nó giới hạn số lượng tài liệu mà các giai đoạn tiếp theo phải xử lý.