M101J MongoDB for Java Week 2
Documents](https://www.youtube.com/watch?feature=player_embedded&v=rAArRbxw0xI)
The CRUD methods take DBObject and the find method returns DBObject, but when you want to create a new instance of DBObject you typically create instances of BasicDBObject which is a LinkedHashMap and guarentees the order of the keys. DBObject is an interface so you can't instantiate it from the New Operator.
public class DocumentRepresentationTest {
public static void main(String[] args) {
BasicDBObject doc = new BasicDBObject();
doc.put("userName", "jyemin");
doc.put("birthDate", new Date(234832423));
doc.put("programmer", true);
doc.put("age", 8) ;
doc.put("languages", Arrays.asList("Java", "C++"));
doc.put("address", new BasicDBObject("street", "20 Main Street")
.append("city", "Westfield")
.append("zip", "56789"));
}
}
Again, BasicDBObject indirectly inherits from LinkedHashMap and implements DBObject. To add a field, use the Map's put method. You can put an array with Arrays.asList(T ...), and you can put a subdocument by instantiating another BasicDBObject, which has a constructor for its first key/value pair, and you can repeatedly call the append method on it, which returns a reference to the object (return this).
Insert](https://www.youtube.com/watch?feature=player_embedded&v=wAGixFmneRI)
The DBCollection class has a method called insert which can take a variable of type DBObject, an array of DBObjects, a List of DBObjects, and even just multiple DBObjects separated by commas, like so:
MongoClient client = new MongoClient(); // No-arg Constructor = localhost, 27017
DB database = client.getDB("course");
DBCollection collection = database.getCollection("insertTest");
DBObject doc = new BasicDBObject().append("x", 1);
DBObject doc2 = new BasicDBObject().append("x", 2);
collection.insert(doc, doc2);
This will cause an error on the second insert:
DBObject doc = new BasicDBObject().append("x", 1);
collection.insert(doc);
collection.insert(doc);
The first insert adds an _id (BSON ObjectID) to the document, and the second insert attempts to insert a document with the same _id, which is illegal.
The following will work, however:
DBObject doc = new BasicDBObject().append("x", 1);
collection.insert(doc);
doc.removeField("_id");
collection.insert(doc);
Count](https://www.youtube.com/watch?feature=player_embedded&v=wgTeReQW7zI)
findOne returns a DBCursor object, which implements Iterator<DBObject>. It is always a good idea to wrap a cursor in a try/finally block, and close the cursor in the finally section.
DBCursor cursor = collection.find();
try {
while (cursor.hasNext()) {
DBObject doc = cursor.next();
System.out.println(doc);
}
} finally {
cursor.close();
}
count() on a DBCollection returns a long with the number of documents in the object.
long count = collection.count();
Criteria](https://www.youtube.com/watch?feature=player_embedded&v=5UtrLdHD06I)
The find method and count method can take a single parameter of DBObject type which acts as the where clause or query criteria on a find.
DBObject query = new BasicDBObject("x", 0);
long count = collection.count(query);
DBCursor cursor = collection.find(query);
Here is an example of a compound query and also how to implement $gt and $lt:
DBObject query = new BassicDBObject("x", 0)
.append("y", new BasicDBObject("$gt", 10)
.append("$lt", 90));
long count = collection.count(query);
DBCursor cursor = collection.find(query);
A cleaner way to do this is to use the QueryBuilder class. Here is an equivalent query:
QueryBuilder builder = QueryBuilder.start("x").is(0)
.and("y").greaterThan(10).lessThan(70);
long count = collection.count(builder.get());
DBCursor cursor = collection.find(builder.get());
The get() method on a QueryBuilder object returns a DBObject.
Selection](https://www.youtube.com/watch?feature=player_embedded&v=oW-0h- Ux3hQ)
Say we have a collection like the following:
Random rand = new Random();
for (int i = 0; i < 10; i++) {
collection.insert(new BasicDBObject("x", rand.nextInt(2))
.append("y", rand.nextInt(100))
.append("z", rand.nextInt(1000)));
}
a Query like the following:
DBObject query = QueryBuilder.start("x").is(0).and("y").greaterThan(10).lessThan(70).get();
and we wanted to return only the y and z fields. We can pass a DBObject as the second parameter to find, just like the mongo shell, to do so:
DBCursor cursor = collection.find(query, new BasicDBObject("x", false));
What if we only wanted the y field (and its _id)?
DBCursor cursor = collection.find(query, new BasicDBObject("y", true));
What if we only wanted the y field without its _id?
DBCursor cursor = collection.find(query, new BasicDBObject("y", true).append("_id", false));
1s and 0s can be passed instead of true and false, as well.
Notation](https://www.youtube.com/watch?feature=player_embedded&v=b8HWPdz9u38)
Limit](https://www.youtube.com/watch?feature=player_embedded&v=sYPs9PlBxrs)
Here is a good example:
DBCursor cursor = collection.find()
.sort(new BasicDBObject("start.x", 1).append("start.y", -1))
.skip(2)
.limit(5);
They can all be chained together. Remember the cursor isn't executed until the next() method is called on it or its iterated over in a foreach loop.
Remove](https://www.youtube.com/watch?feature=player_embedded&v=6n9rN6vzRyg)
Here are all the behaviors of update:
collection.update(new BasicDBObject("_id", "alice")
,new BasicDBObject("age", 24));
collection.update(new BasicDBObject("_id", "alice"),
new BasicDBObject("$set", new BasicDBObject("gender", "F")));
collection.update(new BasicDBObject("_id", "frank"),
new BasicDBObject("$set", new BasicDBObject("gender", "M")), true, false);
collection.update(new BasicDBObject(),
new BasicDBObject("$set", new BasicDBObject("title", "Dr.")), false, true);
findAndModify](https://www.youtube.com/watch?feature=player_embedded&v=PWZMQTsJFGs)