Tìm hiểu về Java Driver trong MongoDB

Trong bài viết dưới đây, chúng tôi sẽ giới thiệu với các bạn một vài tính năng cơ bản của MongoDV Java Driver cũng như cách triển khai và ứng dụng vào thực tế.

Trên thực tế thì việc sử dụng Java driver khá đơn giản. Trước tiên, các bạn cần đảm bảo rằng đã bao gồm driver jar mongo.jar trong đường dẫn classpath chính. Đoạn mã dưới đây được lấy ra từ ví dụ examples/QuickTour.java trong driver.

Tạo kết nối:

Để tạo kết nối tới MongoDB thì điều kiện tối thiểu cần đáp ứng là tên của cơ sở dữ liệu, về mặt kỹ thuật thì database này không cần thiết phải tồn tại, nếu không có thì MongoDB sẽ tự tạo cho người dùng 1 bản. Bên cạnh đó, người dùng còn có thể chỉ định rõ ràng địa chỉ và port của server khi kết nối. Ví dụ dưới đây chỉ ra 3 cách cơ bản để kết nối tới cơ sở dữ liệu có tên là mydb trên máy local:

	import com.mongodb.Mongo;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;

Mongo m = new Mongo(); // or Mongo m = new Mongo( "localhost" ); // or Mongo m = new Mongo( "localhost" , 27017 );

DB db = m.getDB( "mydb" );

Tại thời điểm này, đối tượng db sẽ trở thành kết nối chính tới server MongoDB dành cho 1 database cố định. Và với thành phần này chúng ta sẽ có thể thực hiện được nhiều tác vụ hơn nữa. Tuy nhiên, các bạn cần lưu ý rằng đối tượng Mongo sẽ trở thành 1 pool của quy trình kết nối tới cơ sở dữ liệu, và chúng ta chỉ cần 1 đối tượng của class Mongo với nhiều thread khác nhau (tham khảo thêm tại đây). Về mặt bản chất, class Mongo được thiết kế riêng biệt để trở thành 1 thread an toàn và dễ dàng được chia sẻ giữa nhiều thread khác nhau. Thông thường, các bạn chỉ cần tạo 1 ví dụ dành cho cluster DB và sử dụng trong suốt toàn bộ ứng dụng. Nếu gặp phải trường hợp đặc biệt nào đó mà chúng ta bắt buộc phải tạo nhiều biến mongo thì hãy để ý:

  • Giới hạn trong việc sử dụng nguồn tài nguyên (số lượng kết nối tối đa…) được áp dụng trên 1 biến.
  • Để đóng 1 biến nào đó, hãy sử dụng hàm mongo.close() để xóa sạch dữ liệu về tài nguyên đã được sử dụng.

Quy trình xác nhận (tùy chọn):

MongoDB có thể hoạt động trong chế độ Secure, tại đây tất cả các truy cập tới cơ sở dữ liệu được điều khiển, giám sát bằng tên và mật khẩu. Và khi làm việc như vậy, bất kỳ ứng dụng client nào đều phải cung cấp tên, mật khẩu trước khi thực hiện các thao tác tiếp theo. Trong Java Driver thì chúng ta chỉ cần sử dụng cú pháp lệnh dưới đây khi kết nối tới 1 đối tượng mongo:

	boolean auth = db.authenticate(myUserName, myPassword);

Nếu phần tên và mật khẩu chính xác với thông tin xác nhận trong database, auth sẽ trở thành true, còn nếu không thì sẽ trở thành false (kiểm tra file log của MongoDB). Trên thực tế thì hầu hết mọi người đều sử dụng MongoDB mà không cần phải xác nhận trong 1 môi trường đủ an toàn và bảo mật.

Nhận danh sách Collection:

Về mặt bản chất thì mỗi 1 database đều có 0 hoặc nhiều hơn Collection, và chúng ta có thể lấy được danh sách những thành phần đó từ db:

	Set<String> colls = db.getCollectionNames();

for (String s : colls) { System.out.println(s); }

và giả sử rằng có 2 collection, tên và mật khẩu bên trong database. Kết quả trả về từ hệ thống sẽ bao gồm: 

	name
address

Lấy Collection:

Nếu muốn lấy ra 1 collection bất kỳ để sử dụng, các bạn chỉ cần chỉ định rõ ràng tên của collection đó tới cú pháp getCollection(String collectionName):

	DBCollection coll = db.getCollection("testCollection")

Khi đã có được đối tượng collection này, chúng ta có thể thực hiện các thao tác khác 1 cách dễ dàng, chẳng hạn như insert, query dữ liệu…

Insert Document:

Sau khi lấy được đối tượng collection, các bạn có thể chèn thêm văn bản – Document vào collection đó. Ví dụ, hãy thử tạo 1 document nho nhỏ trong JSON như sau:

	{
   "name" : "MongoDB",
   "type" : "database",
   "count" : 1,
   "info" : {
               x : 203,
               y : 102
             }
}

Khi thực hiện như trên thì có nghĩa là hệ thống đã có 1 văn bản inner được nhúng sẵn ở bên trong. Để làm như vậy, hãy sử dụng class BasicDBObject để tạo văn bản (có bao gồm inner document), và sau đó chèn vào trong Collection bằng cú pháp insert()

	BasicDBObject doc = new BasicDBObject();

doc.put("name", "MongoDB"); doc.put("type", "database"); doc.put("count", 1);

BasicDBObject info = new BasicDBObject();

info.put("x", 203); info.put("y", 102);

doc.put("info", info);

coll.insert(doc);

Tìm Document đầu tiên trong Collection bằng findOne()

Để liệt kê, hiển thị các văn bản đã được chèn trong bước trên, chúng ta chỉ việc sử dụng toán tử findOne để lấy document đầu tiên trong dánh sách collection. Và cách thức này sẽ trả về 1 văn bản duy nhất (chứ không phải dạng DBCursor được tìm thấy và trả về bởi toán tử find()), do vậy rất phù hợp với những trường hợp chỉ có 1 văn bản, và chúng ta không phải “đối mặt” với cursor: 

	DBObject myDoc = coll.findOne();
System.out.println(myDoc);

Kết quả trả về sẽ có dạng như sau:

	{ "_id" : "49902cde5162504500b45c2c" , "name" : "MongoDB" , "type" : "database" , "count" : 1 , "info" : { "x" : 203 , "y" : 102}}

Lưu ý rằng thành phần _id sẽ được tự động gắn vào document bởi MongoDB. Hãy nhớ rằng MongoDB cũng sẽ tự động lưu trữ các thành phần có tên bắt đầu bằng "_"/"$" để sử dụng trong những hệ thống internal sau này.

Gán thêm nhiều văn bản:

Phần document được gán vào collection sẽ có dạng như sau:

	{
   "i" : value
}

Và để thực hiện, chúng ta chỉ cần áp dụng vòng lặp có hiệu quả:

	for (int i=0; i < 100; i++) {
    coll.insert(new BasicDBObject().append("i", i));
}

Lưu ý rằng các bạn có thể chèn nhiều loại văn bản khác nhau vào cùng 1 collection, điều đó cũng có nghĩa rằng MongoDB là 1 dạng schema-free.

Đếm Document trong Collection:

Giờ đây, khi chúng ta đã chèn được 101 văn bản (bao gồm 100 trong vòng loop và 1 thành phần từ ban đầu), thì hoàn toàn có thể kiểm tra những thành phần đó có sử dụng hàm getCount() hay không: 

	System.out.println(coll.getCount());

Hệ thống sẽ trả về kết quả 101 như mong muốn.

Sử dụng Cursor để lấy tất cả Document:

Để làm việc này, chúng ta có thể sử dụng cú pháp find() để trả về đối tượng DBCursor để cho phép người dùng lặp lại những phần văn bản phù hợp với yêu cầu tìm kiếm của query. Do vậy, hãy sử dụng lệnh dưới đây để truy vấn tới tất cả phần Document và liệt kê chúng:

	DBCursor cur = coll.find();

while(cur.hasNext()) { System.out.println(cur.next()); }

Hệ thống sẽ hiển thị đầy đủ 101 document trong collection.

Lấy 1 document duy nhất với câu lệnh query:

Về mặt kỹ thuật, người dùng hoàn toàn có thể tạo câu lệnh query để chuyển cú pháp find() tới bộ tổ hợp văn bản trong collection. Ví dụ, nếu muốn tìm 1 văn bản bất kỳ nào đó có giá trị của trường i là 71 thì làm theo cú pháp sau:

	BasicDBObject query = new BasicDBObject();

query.put("i", 71);

cur = coll.find(query);

while(cur.hasNext()) { System.out.println(cur.next()); }

và hệ thống sẽ trả về đúng 1 document duy nhất:

	{ "_id" : "49903677516250c1008d624e" , "i" : 71 }

Bên cạnh đó, các bạn vẫn thường thấy nhiều ví dụ và tài liệu hướng dẫn trong MongoDB hay sử dụng toán tử $, chẳng hạn như: 

	db.things.find({j: {$ne: 3}, k: {$gt: 10} });

Chúng đại diện cho những khóa String trong Java driver, sử dụng các đối tượng DBObjects nhúng:

	         BasicDBObject query = new BasicDBObject();

query.put("j", new BasicDBObject("$ne", 3)); query.put("k", new BasicDBObject("$gt", 10));

cur = coll.find(query);

while(cur.hasNext()) { System.out.println(cur.next()); }

Lấy nhiều văn bản với 1 câu lệnh query:

Trên thực tế, chúng ta có thể lấy ra nhiều document từ collection chỉ với 1 câu lệnh query duy nhất. Ví dụ, nếu muốn liệt kê toàn bộ văn bản với điều kiện "i" > 50 thì áp dụng lệnh dưới đây: 

	        query = new BasicDBObject();

query.put("i", new BasicDBObject("$gt", 50)); // e.g. find all where i > 50

cur = coll.find(query);

while(cur.hasNext()) { System.out.println(cur.next()); }

hoặc với điều kiện 20 < i <= 30 thì sử dụng lệnh như sau: 

	        query = new BasicDBObject();

query.put("i", new BasicDBObject("$gt", 20).append("$lte", 30)); // i.e. 20 < i <= 30

cur = coll.find(query);

while(cur.hasNext()) { System.out.println(cur.next()); }

Tạo Index:

MongoDB hỗ trợ index, và chúng rất dễ để gán vào collection. Để tạo index, chúng ta chỉ cần xác định rõ trường dữ liệu sẽ được index, và thứ tự sắp xếp theo chuẩn tăng dần – ascending (1) hoặc giảm dần – descending (-1). Câu lệnh dưới đây sẽ tạo ra mục index theo thứ tự tăng dần của trường i: 

	coll.createIndex(new BasicDBObject("i", 1));  // create index on "i", ascending

Lấy danh sách của mục index trong collection:

Cú pháp lệnh chung như sau:

	List<DBObject> list = coll.getIndexInfo();

for (DBObject o : list) { System.out.println(o); }

Và hệ thống sẽ hiển thị danh sách trả về có dạng như sau: 

	{ "name" : "i_1" , "ns" : "mydb.testCollection" , "key" : { "i" : 1} }

Tham khảo về tính năng quản trị:

Đầu tiên là lấy ra danh sách của database bằng lệnh:

	Mongo m = new Mongo();

for (String s : m.getDatabaseNames()) { System.out.println(s); }

Còn nếu muốn xóa cơ sở dữ liệu theo tên thì hãy dùng biến theo kiểu đối tượng tương ứng của Mongo: 

	m.dropDatabase("my_new_db");

Hy vọng rằng những thông tin trên đã có thể giúp các bạn hiểu thêm về một vài tính năng cơ bản của MongoDV Java Driver cũng như cách triển khai và ứng dụng vào thực tế.

Theo Q uản Trị Mạng.