Đối với điều này, hãy sử dụng tổng hợp[] cùng với $unwind. Hãy để chúng tôi tạo một bộ sưu tập với các tài liệu -
> db.demo583.insert[[ .. { .. "details1" : [ .. { .. "details2" : [ .. { .. "isMarried" : true, .. "Name" : "Chris" .. }, .. { .. "isMarried" : true, .. "Name" : "Bob" .. } .. ] .. }, .. { .. "details2" : [ .. { .. "isMarried" : false, .. "Name" : "Chris" .. }, .. { .. "isMarried" : true, .. "Name" : "Mike" .. } .. ] .. } .. ] .. } .. ]]; BulkWriteResult[{ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 1, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ] }]
Hiển thị tất cả các tài liệu từ một bộ sưu tập với sự trợ giúp của phương thức find[] -
> db.demo583.find[];
Điều này sẽ tạo ra đầu ra sau -
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : [ { "details2" : [ { "isMarried" : true, "Name" : "Chris" }, { "isMarried" : true, "Name" : "Bob" } ] }, { "details2" : [ { "isMarried" : false, "Name" : "Chris" }, { "isMarried" : true, "Name" : "Mike" } ] } ] }
Sau đây là truy vấn để lọc tài liệu con theo tài liệu con -
> var q= [ .. { .. "$match": { .. "details1.details2.isMarried": true, .. "details1.details2.Name": "Chris" .. } .. }, .. { .. "$unwind": "$details1" .. }, .. { .. "$unwind": "$details1.details2" .. }, .. { .. "$match": { .. "details1.details2.isMarried": true, .. "details1.details2.Name": "Chris" .. } .. } .. ]; > db.demo583.aggregate[q].pretty[];
Điều này sẽ tạo ra đầu ra sau -
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : { "details2" : { "isMarried" : true, "Name" : "Chris" } } }
Tôi đang lưu trữ các hàng của bảng dưới dạng tài liệu MongoDb, với mỗi cột có một tên. Giả sử bảng có các cột quan tâm này.
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : { "details2" : { "isMarried" : true, "Name" : "Chris" } } }6,
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : { "details2" : { "isMarried" : true, "Name" : "Chris" } } }7,
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : { "details2" : { "isMarried" : true, "Name" : "Chris" } } }8,
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : { "details2" : { "isMarried" : true, "Name" : "Chris" } } }9. Tài liệu MongoDb cũng có một số trường bổ sung tách biệt với dữ liệu bảng, được biểu thị bằng
{
_id: XXXX,
insertDate: ISODate["2012-10-15T21:26:17Z"],
flag: true,
data: {
Identifier: "AB002",
Person: "John002",
Date: ISODate["2013-11-16T21:26:17Z"],
Count: 1
}
}
0. Các cột không cố định [đó là lý do tại sao tôi sử dụng cơ sở dữ liệu không có lược đồ để lưu trữ chúng ở vị trí đầu tiên]Sẽ cần phải thực hiện nhiều truy vấn phức tạp, nhưng cho đến nay vẫn chưa xác định. Tôi không quan tâm lắm đến hiệu suất, mặc dù hiệu suất truy vấn có thể trở thành nút cổ chai. Sau khi được chèn, tài liệu sẽ không bị sửa đổi [thay vào đó, một tài liệu mới có cùng ________ 46 sẽ được tạo] và việc chèn không thường xuyên lắm [giả sử, 1000 tài liệu MongoDb mới mỗi ngày]. Vì vậy, lượng dữ liệu sẽ tăng đều theo thời gian
Thí dụ
Cách tiếp cận đơn giản là có một bộ sưu tập các tài liệu MongoDb như
{
_id: XXXX,
insertDate: ISODate["2012-10-15T21:26:17Z"],
flag: true,
data: {
Identifier: "AB002",
Person: "John002",
Date: ISODate["2013-11-16T21:26:17Z"],
Count: 1
}
}
Bây giờ tôi đã thấy một cách tiếp cận khác [ví dụ: trong câu trả lời được chấp nhận của câu hỏi này], sử dụng mảng có hai trường cho mỗi đối tượng
{
_id: XXXX,
insertDate: ISODate["2012-10-15T21:26:17Z"],
flag: true,
data: [
{ field: "Identifier", value: "AB002" },
{ field: "Person", value: "John001" },
{ field: "Date", value: ISODate["2013-11-16T21:26:17Z"] },
{ field: "Count", value: 1 }
]
}
câu hỏi
Cách tiếp cận thứ 2 có ý nghĩa gì không?
Nếu có, thì làm thế nào để chọn cái nào để sử dụng?
Trong MongoDB, bạn có thể dễ dàng nhúng một tài liệu vào trong một tài liệu khác. Như chúng ta biết rằng trong mongo shell, các tài liệu được biểu diễn bằng dấu ngoặc nhọn [ {} ] và bên trong các dấu ngoặc nhọn này, chúng ta có các cặp giá trị trường. Bây giờ bên trong các trường này, chúng ta có thể nhúng một tài liệu khác bằng cách sử dụng dấu ngoặc nhọn {} và tài liệu này có thể chứa các cặp giá trị trường hoặc tài liệu phụ khác.
Bạn đã học cách sử dụng Mongoose ở mức cơ bản để tạo, đọc, cập nhật và xóa tài liệu trong hướng dẫn trước. Trong hướng dẫn này, chúng ta sẽ tiến thêm một bước vào các tài liệu con
Tài liệu phụ là gì
Trong Mongoose, các tài liệu con là các tài liệu được lồng trong các tài liệu khác. Bạn có thể phát hiện một tài liệu con khi một lược đồ được lồng vào một lược đồ khác
Ghi chú. MongoDB gọi tài liệu con nhúng tài liệu
const childSchema = new Schema[{
name: String
}];
const parentSchema = new Schema[{
// Single subdocument
child: childSchema,
// Array of subdocuments
children: [ childSchema ]
}];
Trong thực tế, bạn không phải tạo một
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
6 riêng như ví dụ trên. Mongoose giúp bạn tạo các lược đồ lồng nhau khi bạn lồng một đối tượng vào một đối tượng khác________số 8Đang cập nhật characterSchema
Giả sử chúng ta muốn tạo một nhân vật tên là Ryu. Ryu có ba chiêu thức đặc biệt
- Hadoken
- Shinryuken
- Tatsumaki Senpukyaku
Ryu cũng có một chiêu cuối gọi là
- Shinku Hadoken
Chúng tôi muốn lưu tên của mỗi lần di chuyển. Chúng tôi cũng muốn lưu các phím cần thiết để thực hiện bước di chuyển đó
Ở đây, mỗi lần di chuyển là một tài liệu con
> db.demo583.find[];0
Bạn cũng có thể sử dụng cú pháp childSchema nếu muốn. Nó làm cho lược đồ Ký tự dễ hiểu hơn
> db.demo583.find[];1
Tạo tài liệu có chứa tài liệu phụ
Có hai cách để tạo tài liệu chứa tài liệu con
- Truyền một đối tượng lồng nhau vào
7// This code is the same as above const parentSchema = new Schema[{ // Single subdocument child: { name: String }, // Array of subdocuments children: [{name: String }] }];
- Thêm thuộc tính vào tài liệu đã tạo
Phương pháp 1. Truyền toàn bộ đối tượng
Đối với phương pháp này, chúng tôi xây dựng một đối tượng lồng nhau có chứa cả tên của Ryu và các bước di chuyển của anh ấy
> db.demo583.find[];3
Sau đó, chúng tôi chuyển đối tượng này vào
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
8> db.demo583.find[];5
Phương pháp 2. Thêm tài liệu con sau
Đối với phương pháp này, trước tiên chúng tôi tạo một ký tự với
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
8> db.demo583.find[];7
Sau đó, chúng tôi chỉnh sửa nhân vật để thêm các bước di chuyển đặc biệt
> db.demo583.find[];8
Sau đó, chúng tôi chỉnh sửa nhân vật để thêm chiêu cuối
> db.demo583.find[];9
Khi chúng tôi hài lòng với
> db.demo583.find[];00, chúng tôi chạy
> db.demo583.find[];01
{ "_id" : ObjectId["5e91d3c4fd2d90c177b5bcc1"], "details1" : [ { "details2" : [ { "isMarried" : true, "Name" : "Chris" }, { "isMarried" : true, "Name" : "Bob" } ] }, { "details2" : [ { "isMarried" : false, "Name" : "Chris" }, { "isMarried" : true, "Name" : "Mike" } ] } ] }2
Cập nhật tài liệu con của mảng
Cách dễ nhất để cập nhật các tài liệu phụ là
- Sử dụng
> db.demo583.find[];
02 để tìm tài liệu - Lấy mảng
- Thay đổi mảng
- Chạy
> db.demo583.find[];
01
Ví dụ: giả sử chúng tôi muốn thêm
> db.demo583.find[];04 vào các bước di chuyển đặc biệt của Ryu. Các khóa cho
> db.demo583.find[];04 là
> db.demo583.find[];06
Đầu tiên, chúng tôi tìm thấy Ryu với
> db.demo583.find[];02
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
0Các tài liệu Mongoose hoạt động giống như các đối tượng JavaScript thông thường. Chúng ta có thể lấy mảng
> db.demo583.find[];08 bằng cách viết
> db.demo583.find[];09
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
1Mảng
> db.demo583.find[];08 này là một mảng JavaScript bình thường.
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
2Chúng ta có thể sử dụng phương pháp
> db.demo583.find[];11 để thêm một mục mới vào
> db.demo583.find[];08,
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
3Sau khi cập nhật
> db.demo583.find[];08, ta chạy
> db.demo583.find[];01 để lưu Ryu vào cơ sở dữ liệu
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
4Cập nhật một văn bản phụ
Việc cập nhật các tài liệu phụ đơn lẻ thậm chí còn dễ dàng hơn. Bạn có thể chỉnh sửa tài liệu trực tiếp như một đối tượng bình thường
Giả sử chúng ta muốn đổi tên cuối cùng của Ryu từ Shinku Hadoken thành Dejin Hadoken. Những gì chúng tôi làm là
- Sử dụng
> db.demo583.find[];
02 để có được Ryu - Thay đổi
> db.demo583.find[];
16 trong> db.demo583.find[];
17 - Chạy
> db.demo583.find[];
01
// This code is the same as above
const parentSchema = new Schema[{
// Single subdocument
child: { name: String },
// Array of subdocuments
children: [{name: String }]
}];
5Nếu bạn thích bài viết này, hãy ủng hộ tôi bằng cách chia sẻ bài viết này trên Twitter hoặc mua cho tôi một ly cà phê 😉. Nếu bạn phát hiện lỗi đánh máy, tôi đánh giá cao nếu bạn có thể sửa nó trên GitHub. Cảm ơn bạn.