Một số hệ quản trị cơ sở dữ liệu phổ biến – Phần 4: Tìm hiểu MongoDB
Lần đầu tiên được phát hành công khai vào năm 2009, MongoDB (thường được gọi là Mongo) nhanh chóng trở thành một trong những cơ sở dữ liệu NoSQL được sử dụng rộng rãi nhất hiện nay và vẫn ở những vị trí top đầu cho đến ngày nay. MongoDB được thiết kế như một cơ sở dữ liệu có thể mở rộng—cái tên Mongo bắt nguồn từ từ “khổng lồ”—với hiệu suất và khả năng truy cập dữ liệu dễ dàng làm mục tiêu thiết kế cốt lõi. Nó là một cơ sở dữ liệu document - tài liệu, cho phép bạn lưu trữ các đối tượng được lồng vào nhau ở bất kỳ độ sâu nào bạn muốn và bạn có thể truy vấn dữ liệu lồng nhau đó theo kiểu đặc biệt. Nó không có lược đồ (tương tự như HBase), vì vậy các tài liệu có thể chứa các trường hoặc loại mà không tài liệu nào khác trong collection.
Mongo là một cơ sở dữ liệu JSON document (mặc dù về mặt kỹ thuật, dữ liệu được lưu trữ ở dạng JSON nhị phân được gọi là BSON). Một JSON documnet có thể được ví như một hàng của bảng quan hệ mà không có lược đồ, các giá trị của nó có thể lồng vào nhau tùy ý. Hãy tham khảo đoạn ví dụ bên dưới
{
"_id" : ObjectId("4d0b6da3bb30773266f39fea"),
"country" : {
"$ref" : "countries",
"$id" : ObjectId("4d0e6074deb899521a8309e")
},
"famous_for" : {
"beer",
"food"
}
}
Theo một số cách nghĩ, cơ sở dữ liệu tài liệu có quy trình công việc ngược lại so với cơ sở dữ liệu quan hệ. Các cơ sở dữ liệu quan hệ như PostgreSQL giả định rằng bạn biết bạn muốn lưu trữ dữ liệu nào mà không nhất thiết phải biết bạn muốn sử dụng dữ liệu đó như thế nào; điều quan trọng là cách bạn lưu trữ nó. Sự linh hoạt của truy vấn được xem xét trước khi lưu trữ. Cơ sở dữ liệu document yêu cầu bạn đưa ra một số giả định về cách bạn muốn sử dụng dữ liệu của mình, nhưng bỏ qua xem xét về chính xác những gì bạn muốn lưu trữ. Bạn có thể nhanh chóng thực hiện các thay đổi “lược đồ” cơ bản, nhưng bạn có thể phải trả giá cho các quyết định thiết kế của mình sau này.
CRUD và Nesting
Chúng ta sẽ dành bài viết này để tìm hiểu và thực hiện một số thao tác CRUD và kết thúc bằng cách thực hiện các truy vấn lồng nhau trong MongoDB. Như thường lệ, mình sẽ không hướng dẫn bạn các bước cài đặt, nhưng nếu bạn truy cập trang web Mongo, bạn có thể tải xuống bản dựng cho hệ điều hành của mình hoặc tìm hướng dẫn về cách xây dựng từ nguồn. Nếu bạn sử dụng OS X, bạn nên cài đặt qua Homebrew (brew install mongodb). Nếu bạn sử dụng Debian/Ubuntu, hãy thử apt-get package riêng của MongoDB.
Để tránh lỗi, trước tiên Mongo yêu cầu bạn tạo thư mục nơi mongod sẽ lưu trữ dữ liệu của nó. Một vị trí phổ biến là /data/db. Đảm bảo người dùng có quyền đọc và ghi vào thư mục này. Nếu nó chưa chạy, bạn có thể kích hoạt bằng cách chạy mongod
Command-line
Để tạo cơ sở dữ liệu mới có tên book, trước tiên hãy chạy lệnh này trong terminal. Nó sẽ kết nối với của số command
mongo book
Nhập help trong console là một ý tưởng tốt để bắt đầu. Chúng ta hiện đang ở trong cơ sở dữ liệu book, nhưng bạn có thể xem những cơ sở dữ liệu khác thông qua show dbs và chuyển đổi cơ sở dữ liệu bằng cách sử lệnh tương ứng
Tạo một document trong Mongo dễ dàng như thêm một bản ghi ban đầu vào collection. Bởi vì Mongo không có lược đồ, nên không cần xác định trước bất cứ điều gì; chỉ cần sử dụng nó là đủ. Hơn nữa, cơ sở dữ liệu book không thực sự tồn tại cho đến khi thêm các giá trị vào đó lần đầu tiên. Đoạn mã sau tạo/chèn collection towns:
> db.towns.insert({
name: "New York",
population: 22200000,
lastCensus: ISODate("2016-07-01"),
famousFor: [ "the MOMA", "food", "Derek Jeter" ],
mayor : {
name : "Bill de Blasio",
party : "D"
}
})
Trong phần trước, chúng tôi đã nói rằng các tài liệu lưu trữ là JSON (đúng hơn là BSON ẩn bên dưới), vì vậy chúng tôi thêm các tài liệu mới dưới dạng JSON (tương tự sau này với CouchDB và ở mức độ thấp hơn là DynamoDB).
Với lệnh show collections, bạn có thể xác minh collection đang tồn tại.
> show collections
------------------
towns
Chúng ta đã tạo collection towns bằng cách lưu trữ một đối tượng trong đó. Chúng ta có thể liệt kê nội dung của một collection thông qua find(). Lưu ý: ở đây đã định dạng đầu ra ở đây để dễ đọc, nhưng đầu ra của bạn có thể chỉ xuất ra dưới dạng một dòng
> db.towns.find()
{
"_id" : ObjectId("59093bc08c87e2ff4157bd9f"),
"name" : "New York",
"population" : 22200000,
"lastCensus" : ISODate("2016-07-01T00:00:00Z"),
"famousFor" : [ "the MOMA", "food", "Derek Jeter" ],
"mayor" : {
"name" : "Bill de Blasio",
"party" : "I"
}
}
Không giống như cơ sở dữ liệu quan hệ, Mongo không hỗ trợ server-side join. Một lệnh gọi duy nhất sẽ truy xuất một document và tất cả nội dung lồng nhau của nó.
Bạn có thể nhận thấy rằng đầu ra JSON của town mới được chèn của bạn chứa trường _id thuộc loại ObjectId. Điều này giống như tăng SERIAL một khóa chính dạng số trong PostgreSQL. ObjectId luôn là 12 byte, bao gồm dấu thời gian, client ID, client process ID và bộ đếm tăng dần 3 byte
Điều tuyệt vời về sơ đồ đánh số tự động này là mỗi process trên mỗi máy có thể xử lý việc tạo ID của chính nó mà không xung đột với các phiên bản mongod khác. Sự lựa chọn thiết kế này thể hiện bản chất phân tán chung của Mongo.
Javascript
Ngôn ngữ native của Mongo là JavaScript. Bạn sẽ sử dụng nó khi thực hiện những việc phức tạp như truy vấn mapreduce hoặc đơn giản như yêu cầu trợ giúp.
> db.help()
> db.towns.help()
Các lệnh này sẽ liệt kê các chức năng có sẵn liên quan đến đối tượng đã cho. db là một đối tượng JavaScript chứa thông tin về cơ sở dữ liệu hiện tại. db.x là một đối tượng JavaScript đại diện cho một bộ sưu tập (có tên là x). Các lệnh chỉ là các hàm JavaScript.
> typeof db
object
> typeof db.towns
object
> typeof db.towns.insert
function
Nếu bạn muốn kiểm tra mã nguồn của một hàm, hãy gọi nó mà không có tham số hoặc dấu ngoặc đơn.
> db.towns.insert
function (obj, options, _allowDot) {
if (!obj)
throw Error("no object passed to insert!");
var flags = 0;
// etc.
}
Hãy điền thêm một vài document vào collection town của chúng ta bằng cách tạo hàm JavaScript riêng.
function insertCity(
name, population, lastCensus,
famousFor, mayorInfo
) {
db.towns.insert({
name: name,
population: population,
lastCensus: ISODate(lastCensus),
famousFor: famousFor,
mayor : mayorInfo
});
}
Bạn có thể dán mã này vào shell. Sau đó, chúng ta có thể gọi nó
> insertCity("Punxsutawney", 6200, '2016-01-31',
["Punxsutawney Phil"], { name : "Richard Alexander" })
-------------------------------------------------------------------------
> insertCity("Portland", 582000, '2016-09-20',
["beer", "food", "Portlandia"], { name : "Ted Wheeler", party : "D" })
Bây giờ chúng ta sẽ có ba town trong collection của mình, bạn có thể xác nhận điều này bằng cách gọi db.towns.find() như trước đây.
Nhiều điều thú vị hơn với Mongo
Trước đó, chúng tôi đã gọi hàm find() không có tham số để lấy tất cả tài liệu. Để truy cập một document cụ thể, bạn chỉ cần đặt thuộc tính _id. _id thuộc loại ObjectId, do đó, để truy vấn, bạn phải chuyển đổi một chuỗi bằng cách gói nó trong một hàm ObjectId(str).
> db.towns.find({ "_id" : ObjectId("59094288afbc9350ada6b807") })
{
"_id" : ObjectId("59094288afbc9350ada6b807"),
"name" : "Punxsutawney",
"population" : 6200,
"lastCensus" : ISODate("2016-01-31T00:00:00Z"),
"famousFor" : [ "Punxsutawney Phil" ],
"mayor" : { "name" : "Richard Alexander" }
}
Hàm find() cũng chấp nhận một tham số thứ hai tùy chọn: một đối tượng trường có thể sử dụng để lọc những trường nào được truy xuất. Nếu chỉ muốn tên thị trấn (cùng với _id), hãy thử đoạn code dưới đây
> db.towns.find({ _id : ObjectId("59094288afbc9350ada6b807") }, { name : 1 })
{
"_id" : ObjectId("59093e9eafbc9350ada6b803"),
"name" : "Punxsutawney"
}
Để truy xuất tất cả các trường ngoại trừ tên, hãy đặt name thành 0 (hoặc false hoặc null)
> db.towns.find({ _id : ObjectId("59094288afbc9350ada6b807") }, { name : 0 })
{
"_id" : ObjectId("59093e9eafbc9350ada6b803"),
"population" : 6200,
"lastCensus" : ISODate("2016-01-31T00:00:00Z"),
"famousFor" : [ "Punxsutawney Phil" ]
}
Tương tự như trong PostgreSQL, trong Mongo, bạn có thể xây dựng các truy vấn đặc biệt trên cơ sở các giá trị trường, phạm vi hoặc kết hợp các tiêu chí. Để tìm tất cả các town bắt đầu bằng chữ P và có dân số dưới 10.000 người, bạn có thể sử dụng biểu thức chính quy Perl-compatible (PCRE) và toán tử phạm vi. Truy vấn này sẽ trả về đối tượng JSON cho Punxsutawney, nhưng chỉ bao gồm các trường tên và dân số:
> db.towns.find(
{ name : /^P/, population : { $lt : 10000 } },
{ _id: 0, name : 1, population : 1 }
)
{ "name" : "Punxsutawney", "population" : 6200 }
Các toán tử điều kiện trong Mongo tuân theo định dạng của trường: { $op : value }, trong đó $op là một phép toán như $ne (không bằng) hoặc $gt (lớn hơn). Bạn có thể muốn một cú pháp ngắn hơn, như field < giá trị. Nhưng đây là mã JavaScript, không phải ngôn ngữ truy vấn dành riêng cho field, vì vậy các truy vấn phải tuân thủ các quy tắc cú pháp JavaScript (ở các bài sau bạn sẽ thấy cách sử dụng cú pháp ngắn hơn trong một số trường hợp nhất định, nhưng bây giờ chúng ta sẽ bỏ qua cú pháp đó).
Tuy nhiên đối với JavaScript bạn có thể xây dựng các hoạt động như đối tượng. Ở đây là ví dụ xây dựng tiêu chí dân số phải từ 10.000 đến 1 triệu người.
> var population_range = {
$lt: 1000000,
$gt: 10000
}
> db.towns.find(
{ name : /^P/, population : population_range },
{ name: 1 }
)
{ "_id" : ObjectId("59094292afbc9350ada6b808"), "name" : "Portland" }
Ngoài phạm vi số, ta cũng có thể truy xuất phạm vi ngày. Ví dụ: ta có thể tìm thấy tất cả các tên có lastCensus (ngày điều tra dân số) cuối cùng lớn hơn hoặc bằng ngày 1 tháng 6 năm 2016, như sau:
> db.towns.find(
{ lastCensus : { $gte : ISODate('2016-06-01') } },
{ _id : 0, name: 1 }
)
----------------------
{ "name" : "New York" }
{ "name" : "Portland" }
Lưu ý cách loại bỏ trường _id trong đầu ra một cách rõ ràng bằng cách đặt nó thành 0.
Đi "sâu" hơn với Mongo
Mongo thích dữ liệu mảng lồng nhau. Bạn có thể truy vấn bằng cách truy vấn theo các giá trị chính xác:
> db.towns.find(
{ famousFor : 'food' },
{ _id : 0, name : 1, famousFor : 1 }
)
-----------------------------------------------------------------------------
{ "name" : "New York", "famousFor" : [ "the MOMA", "food", "Derek Jeter" ] }
{ "name" : "Portland", "famousFor" : [ "beer", "food", "Portlandia" ] }
hoặc so khớp giá trị một phần như sau:
> db.towns.find(
{ famousFor : /moma/ },
{ _id : 0, name : 1, famousFor : 1 }
)
-------------------------------------------------------------
{ "name" : "New York", "famousFor" : [ "the MOMA", "food" ] }
hoặc truy vấn theo tất cả các giá trị phù hợp:
> db.towns.find(
{ famousFor : { $all : ['food', 'beer'] } },
{ _id : 0, name:1, famousFor:1 }
)
-----------------------------------------------------------------------
{ "name" : "Portland", "famousFor" : [ "beer", "food", "Portlandia" ] }
hoặc thiếu các giá trị phù hợp:
> db.towns.find(
{ famousFor : { $nin : ['food', 'beer'] } },
{ _id : 0, name : 1, famousFor : 1 }
)
------------------------------------------------------------------
{ "name" : "Punxsutawney", "famousFor" : [ "Punxsutawney Phil" ] }
Nhưng sức mạnh thực sự của Mongo bắt nguồn từ khả năng đào sâu vào tài liệu và trả về kết quả của các tài liệu phụ được lồng sâu. Để truy vấn một tài liệu con, tên trường của bạn là một chuỗi ngăn cách các lớp lồng nhau bằng một dấu chấm. Chẳng hạn, bạn có thể tìm các thị trấn có thị trưởng từ Đảng Dân chủ:
> db.towns.find(
{ 'mayor.party' : 'D' },
{ _id : 0, name : 1, mayor : 1 }
)
-------------------------------------------------------------------------------
{ "name" : "New York", "mayor" : { "name" : "Bill de Blasio", "party" : "D" } }
{ "name" : "Portland", "mayor" : { "name" : "Ted Wheeler", "party" : "D" } }
hoặc những người có thị trưởng không có đảng phái:
> db.towns.find(
{ 'mayor.party' : { $exists : false } },
{ _id : 0, name : 1, mayor : 1 }
)
----------------------------------------------------------------------
{ "name" : "Punxsutawney", "mayor" : { "name" : "Richard Alexander" } }
Các truy vấn trước đây rất phù hợp nếu bạn muốn tìm tài liệu có một trường khớp duy nhất, nhưng nếu bạn cần khớp nhiều trường của một tài liệu con thì sao?
elemMatch
Chúng ta sẽ tiếp tục với $elemMatch. Hãy tạo một collection lưu trữ các quốc gia. Lần này, chúng ta sẽ ghi đè từng _id thành một chuỗi do chúng ta lựa chọn thay vì một mã định danh được tạo tự động.
> db.countries.insert({
_id : "us",
name : "United States",
exports : {
foods : [
{ name : "bacon", tasty : true },
{ name : "burgers" }
]
}
})
> db.countries.insert({
_id : "ca",
name : "Canada",
exports : {
foods : [
{ name : "bacon", tasty : false },
{ name : "syrup", tasty : true }
]
}
})
> db.countries.insert({
_id : "mx",
name : "Mexico",
exports : {
foods : [{
name : "salsa",
tasty : true,
condiment : true
}]
}
})
Để kiểm tra các quốc gia đã được thêm vào, chúng ta có thể thực thi hàm đếm với kết quả mong đợi là 3.
> db.countries.count()
------
3
Hãy tìm một quốc gia không chỉ xuất khẩu thịt xông khói mà còn xuất khẩu thịt xông khói ngon.
> db.countries.find(
{ 'exports.foods.name' : 'bacon', 'exports.foods.tasty' : true },
{ _id : 0, name : 1 }
)
-----------------------------
{ "name" : "United States" }
{ "name" : "Canada" }
Nhưng đây không phải là những gì chúng ta mong muốn. Mongo trả lại Canada vì nước này xuất khẩu thịt xông khói và xuất khẩu xi-rô ngon. $elemMatch sẽ giúp chúng ta. Nó chỉ định rằng nếu một tài liệu (hoặc tài liệu lồng nhau) phù hợp với tất cả các tiêu chí, tài liệu đó sẽ được tính là phù hợp.
> db.countries.find(
{
'exports.foods' : {
$elemMatch : {
name : 'bacon',
tasty : true
}
}
},
{ _id : 0, name : 1 }
)
----------------------------
{ "name" : "United States" }
Tiêu chí $elemMatch cũng có thể sử dụng các toán tử nâng cao. Bạn có thể tìm thấy bất kỳ quốc gia nào xuất khẩu một loại thực phẩm ngon cũng có nhãn gia vị:
> db.countries.find(
{
'exports.foods' : {
$elemMatch : {
tasty : true,
condiment : { $exists : true }
}
}
},
{ _id : 0, name : 1 }
)
-----------------------
{ "name" : "Mexico" }
Mexico là kết quả mong muốn ở đây
Boolean Ops
Cho đến nay, tất cả các tiêu chí truy vấn là các phép so sánh. Nếu bạn cố gắng tìm một quốc gia có tên United States và _id của mx, Mongo sẽ không mang lại kết quả nào
> db.countries.find(
{ _id : "mx", name : "United States" },
{ _id : 1 }
)
Tuy nhiên, tìm kiếm cái này hay cái kia bằng $or sẽ trả về hai kết quả. Hãy coi bố cục này giống như ký hiệu tiền tố: OR A B.
db.countries.find(
{
$or : [
{ _id : "mx" },
{ name : "United States" }
]
},
{ _id:1 }
)
----------------
{ "_id" : "us" }
{ "_id" : "mx" }
Có rất nhiều toán tử trong Mongo mà bài viết không thể trình bày hết ở đây, nhưng mình hy vọng điều này đã giúp bạn cảm nhận được các khả năng truy vấn mạnh mẽ của MongoDB.
Command | Mô tả |
$regex | Regex |
$ne | Not equal to - so sánh không bằng |
$lt | Less than - so sánh nhỏ hơn |
$lte | Less than or equal to - so sánh nhỏ hơn hoặc bằng |
$gt | Greater than - so sánh lớn hơn |
$gte | Greater than or equal - so sánh lớn hơn hoặc bằng |
$exists | Check for the existence - kiểm tra tồn tại |
$all | Match all elements in an array - khớp tất cả phần tử trong mảng |
$in | Match any elements in an array - khớp bất kỳ phần tử nào trong mảng |
$nin | Does not match any elements in an array - khớp bất kỳ phần tử nào trong mảng |
$elemMatch | Match all fields in an array of nested documents - khớp tất cả trường trong một mảng tài liệu lồng nhau |
$or | or |
$nor | Not or |
$size | Match array of given size - So khớp mảng với kích thước cho trước |
$mod | Modulus |
$type | Match if field is a given datatype - so khớp kiểu dữ liệu của trường |
$not | Negate the given operator check |
Bạn có thể tìm thấy tất cả các lệnh trên trên web chính thức của MongoDB hoặc lấy một bảng cheat từ trang web Mongo.
Updating
Chúng ta có một vấn đề. New York và Punxsutawney đã đủ độc đáo, nhưng chúng ta đã thêm Portland, Oregon hay Portland, Maine (hoặc Texas hay những nơi khác)? Hãy cập nhật collection town để thêm một số tiểu bang của Hoa Kỳ.
Hàm update (criteria, operation) yêu cầu hai tham số. Đầu tiên là một criteria — kiểu đối tượng mà bạn sẽ chuyển đến find(). Tham số thứ hai là một đối tượng có các trường sẽ thay thế (các) tài liệu phù hợp hoặc một thao tác sửa đổi. Trong trường hợp này, công cụ sửa đổi là $set state trường bằng chuỗi OR.
db.towns.update(
{ _id : ObjectId("4d0ada87bb30773266f39fe5") },
{ $set : { "state" : "OR" } }
);
Bạn có thể thắc mắc tại sao thao tác $set lại được yêu cầu. Mongo không nghĩ về các thuộc tính; nó chỉ có một sự hiểu biết tiềm ẩn bên trong về các thuộc tính vì lý do tối ưu hóa. Mongo là định hướng tài liệu. Bạn sẽ hiếm khi muốn một cái gì đó như thế này (chú ý thiếu thao tác $set):
db.towns.update(
{ _id : ObjectId("4d0ada87bb30773266f39fe5") },
{ state : "OR" }
);
Thao tác này sẽ thay thế toàn bộ tài liệu phù hợp bằng tài liệu bạn đã cung cấp ({ state : "OR" }). Vì bạn không đưa cho nó một lệnh như $set, Mongo cho rằng bạn chỉ muốn bật chúng lên, vì vậy hãy cẩn thận.
Chúng ta có thể xác minh rằng bản cập nhật của mình đã thành công bằng cách tìm lại nó (lưu ý rằng mình sử dụng findOne() để chỉ truy xuất một đối tượng phù hợp).
db.towns.findOne({ _id : ObjectId("4d0ada87bb30773266f39fe5") })
{
"_id" : ObjectId("4d0ada87bb30773266f39fe5"),
"famousFor" : [
"beer",
"food",
"Portlandia"
],
"lastCensus" : "Thu Sep 20 2017 00:00:00 GMT-0700 (PDT)",
"mayor" : {
"name" : "Sam Adams",
"party" : "D"
},
"name" : "Portland",
"population" : 582000,
"state" : "OR"
}
Bạn có thể làm nhiều hơn $set. $inc (tăng một số) là điều khá hữu ích. Hãy tăng dân số của Portland lên 1.000 người.
db.towns.update(
{ _id : ObjectId("4d0ada87bb30773266f39fe5") },
{ $inc : { population : 1000} }
)
Có nhiều thao tác hơn thế này, chẳng hạn như toán tử vị trí $ cho mảng. Các thao tác mới được thêm vào thường xuyên và được cập nhật tại trang web chính thức của Mongo
References
Như chúng tôi đã đề cập trước đây, Mongo không được xây dựng để thực hiện các phép join. Do tính chất phân tán của nó, joins trong Mongo sẽ hoạt động khá kém hiệu quả. Tuy nhiên, đôi khi nó hữu ích cho các tài liệu để tham khảo lẫn nhau. Trong những trường hợp này, cộng đồng Mongo khuyên bạn nên sử dụng cấu trúc như { $ref : "collection_name", $id : "reference_id" }. Ví dụ: chúng ta có thể cập nhật bộ sưu tập các thị trấn để chứa tham chiếu đến tài liệu ở các quốc gia.
> db.towns.update(
{ _id : ObjectId("59094292afbc9350ada6b808") },
{ $set : { country: { $ref: "countries", $id: "us" } } }
)
Bây giờ bạn có thể truy xuất Portland từ collection thị trấn của mình
> var portland = db.towns.findOne(
{ _id : ObjectId("59094292afbc9350ada6b808") }
)
Sau đó, để truy xuất quốc gia của thị trấn, bạn có thể truy vấn bộ sưu tập quốc gia bằng cách sử dụng $id được lưu trữ
> db.countries.findOne({ _id: portland.country.$id })
Sau đó, để truy xuất quốc gia của thị trấn, bạn có thể truy vấn bộ sưu tập quốc gia bằng cách sử dụng $id được lưu trữ
> var portlandCountryRef = portland.country.$ref;
> db[portlandCountryRef].findOne({ _id: portland.country.$id })
Hai truy vấn cuối cùng là tương đương
Deleting
Việc xóa tài liệu khỏi bộ sưu tập rất đơn giản. Chỉ cần thay thế hàm find() bằng lệnh gọi remove() và tất cả các tài liệu phù hợp với tiêu chí đã cho sẽ bị xóa. Điều quan trọng cần lưu ý là toàn bộ tài liệu phù hợp sẽ bị xóa, không chỉ một phần tử phù hợp hoặc tài liệu con phù hợp.
Ở đây mình khuyên bạn nên chạy find() để xác minh tiêu chí của mình trước khi chạy remove(). Hãy loại bỏ tất cả các quốc gia xuất khẩu thịt xông khói không ngon
> var badBacon = {
'exports.foods' : {
$elemMatch : {
name : 'bacon',
tasty : false
}
}
}
> db.countries.find(badBacon)
{
"_id" : ObjectId("4d0b7b84bb30773266f39fef"),
"name" : "Canada",
"exports" : {
"foods" : [
{
"name" : "bacon",
"tasty" : false
},
{
"name" : "syrup",
"tasty" : true
}
]
}
}
Mọi thứ trông có vẻ tốt. Hãy loại bỏ nó
> db.countries.remove(badBacon)
> db.countries.count()
---------------------------------
2
Bây giờ khi bạn chạy count(), hãy xác minh rằng chỉ còn lại hai quốc gia. Nếu vậy, quá trình xóa với tham số đã thành công!
Tóm tắt
Trong bài viết này chúng ta đã tìm hiểu cơ bản về MongoDB. Bài này cũng trình bày cách để lưu trữ dữ liệu có cấu trúc lồng nhau dưới dạng các đối tượng JSON và truy vấn dữ liệu đó ở bất kỳ độ sâu nào. Bài viết cũng giới thiệu một tài liệu có thể được hình dung dưới dạng một hàng không lược đồ trong mô hình quan hệ, được khóa bởi một _id được tạo. Một bộ tài liệu (document) được gọi là một bộ sưu tập (collection) trong Mongo, tương tự như một bảng trong PostgreSQL nhưng cũng khá khác