Get Collections in Java from MongoDB - java

I have a local MongoDB instance running via shell on windows 10.
University provided a Java Project for us to learn about queries.
Now, I have a database ("imdb") and want to get two collections from it ("movies","tweets").
The problem is, one the one hand
List<String> test = mongo.getDatabaseNames();
System.out.println(test); //prints [admin,config,imdb,local]
...
db = mongo.getDB("imdb");
System.out.println(db.getCollectionNames()); //prints []
There seem to be no collections on imdb but
db.createCollection("movies", new BasicDBObject());
Returns a com.mongodb.CommandFailureException, stating that a collection 'imdb.movies' already exists.
So how do I ensure that Java actually "loads" the Collections?
For Clarification: My goal is to have
System.out.println(db.getCollectionNames());
to print [movies,tweets] instead of []

You could try
Set<String> colls = db.getCollectionNames();
for (String s : colls) {
System.out.println(s);
}
ref: code examples

Which version of mongodb shell you're using
If it's before 3.0, it will return no data for db.getCollectionNames() command
ref: mongodb docs

Since version 3.0 you should use MongoDatabase.listCollectionNames() method.
http://mongodb.github.io/mongo-java-driver/3.8/driver/tutorials/databases-collections/#get-a-list-of-collections
MongoDatabase db = client.getDatabase(dbName);
MongoIterable<String> names = db.listCollectionNames();

You can do like this:
//If you don't need connection's configures. i.e. your mongo is in you localhost at 127.0.0.1:27017
MongoClient cliente = new MongoClient(); //to connect into a mongo DB
MongoDatabase mongoDb = client.getDatabase("imdb"); //get database
MongoCollection<Document> robosCollection = mongoDb.getCollection("movies"); //get the name of the collection that you want
MongoCursor<Document> cursor = robosCollection.find().cursor();//Mongo Cursor interface implementing the iterator protocol
cursor.forEachRemaining(System.out::println); //print all documents in Collection using method reference

Related

Execute MongoTemplate.aggregate without row retrival

I'm using the Spring Mongo driver to execute a large mongo aggregation statement that will run for a period of time. The output stage of this aggregation writes the output of the aggregation into a new collection. At no point do I need to retrieve the results of this aggregation in-memory.
When I run this in Spring boot, the JVM is running out of memory doing row retrieval, although I'm not using or storing any of the results.
Is there a way to skip row retrieval using MongoTemplate.aggregate?
Ex:
mongoTemplate.aggregate(Aggregation.newAggregation(
Aggregation.sort(new Sort(new Sort.Order(Sort.Direction.DESC, "createdOn"))),
Aggregation.group("accountId")
.first("bal").as("bal")
.first("timestamp").as("effectiveTimestamp"),
Aggregation.project("_id", "effectiveTimestamp")
.andExpression("trunc(bal * 10000 + 0.5) / 100").as("bal"),
aggregationOperationContext -> new Document("$addFields", new Document("history",Arrays.asList(historyObj))),
// Write results out to a new collection - Do not store in memory
Aggregation.out("newBalance")
).withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).build()),
"account", Object.class
);
Use AggregationOption - skipOutput() . This will not return a result in case of aggregation pipeline contains $out/$merge operation.
mongoTemplate.aggregate(aggregation.withOptions(newAggregationOptions().skipOutput().allowDiskUse(true).build()), "collectionNme", EntityClass.class);
If you are using MongoDriver without framework.
MongoClient client = MongoClients.create("mongodb://localhost:27017");
MongoDatabase database = client.getDatabase("my-collection");
MongoCollection<Document> model = database.getCollection(collectionName);
AggregateIterable<Document> aggregateResult = model.aggregate(bsonListOfAggregationPipeline);
// instead iterating over call toCollection() to skipResult
aggregateIterable.toCollection();
References:
https://jira.mongodb.org/browse/JAVA-3700
https://developer.mongodb.com/community/forums/t/mongo-java-driver-out-fails-in-lastpipelinestage-when-aggregate/9784
I was able to resolve this by using
MongoTempalte.aggregateStream(...).withOptions(Aggregation.newAggregationOptions().cursorBatchSize(0).build)

how can i create mongodb database from java

I can drop a database with the following statement:
MongoClient mongo = new MongoClient("localhost", 27017);
mongo.dropDatabase("d");
How can I create a database?
If you are using driver 3.1.1 or later:
Refer to this answer:
Calling getDatabase doesn't in fact create new database because
operation is lazy - it returns database representation. Calling any
modifiable operation (e.g. createCollection):
will create new database for you if it is not present if present it
will get database for you But remember that you have to call any
operation which actually performs something - like create. If you just
call getDatabase it won't create it.
NOTE
The documentation does not provide this information, hopefully, they update it. But long answer short, it only creates it after you call an operation on it.
MongoClient mongoClient = new MongoClient();
DB db = mongoClient.getDB("database name");
If database is not present, MongoDB will create it for you.

MongoDB Java driver 3.2: parallel scan

the mongo java driver has an old (and through deprecation of MongoClient.getDB essentially deprecated) method to explicitly perform a parallel scan on a collection.
As far as I can see, this is something along the lines of:
DB db = mongoClient.getDB("mydb");
DBCollection coll = db.getCollection("testCollection");
ParallelScanOptions parallelScanOptions = ParallelScanOptions
.builder()
.numCursors(4)
.batchSize(1000)
.build();
List<Cursor> cursors = coll.parallelScan(parallelScanOptions);
...
The question is: is there a new alternative in driver 3.2 (without using the deprecated DB API)?
You can utilise runCommand() to execute parallelCollectionScan command directly.
For example:
MongoClient client = new MongoClient(new ServerAddress());
MongoDatabase database = client.getDatabase("databaseName");
Document commandResult = database.runCommand(new Document("parallelCollectionScan", "collectionName").append("numCursors", 3));
See also cursor batches

Mongo insert $currentDate in Java Driver

I've got a question about $currentDate
What is the best way to insert a document in mongo db so that it contains the "server time" (like ''now()'' in some RDBMSs) using the Java Driver?
For example, lest say I have a document like:
{
name : "John",
birthday : <$currentDate_goes_here>
}
What I want is to insert the document so that the evaluation of the date would be done by mongo server at the time of insertion on the server side.
This is critical because our servers might not be totally synchronized and there is a need to have the time we can rely on (for example the time on mongo server).
I'm using a standard java driver for mongo, so any code snippet in Java will be more than welcome.
This is what I've tried so far
MongoClient mongoClient = new MongoClient();
DB sampleDB = mongoClient.getDB("sampleDB");
BasicDBObject update =
new BasicDBObject("$set", new BasicDBObject("name","john")
.append("$currentDate", new BasicDBObject("birthday",true)));
sampleDB.getCollection("col1").insert(update);
This thing fails on the following exception:
java.lang.IllegalArgumentException: Document field names can't start with '$' (Bad Key: '$set')
at com.mongodb.DBCollection.validateKey(DBCollection.java:1845)
at com.mongodb.DBCollection._checkKeys(DBCollection.java:1803)
at com.mongodb.DBCollection._checkObject(DBCollection.java:1790)
at com.mongodb.DBCollectionImpl.applyRulesForInsert(DBCollectionImpl.java:392)
at com.mongodb.DBCollectionImpl.insertWithCommandProtocol(DBCollectionImpl.java:381)
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:186)
at com.mongodb.DBCollectionImpl.insert(DBCollectionImpl.java:165)
at com.mongodb.DBCollection.insert(DBCollection.java:93)
at com.mongodb.DBCollection.insert(DBCollection.java:78)
at com.mongodb.DBCollection.insert(DBCollection.java:120)
In which case the answer is fairly simple. It is really about serializing from java BasicDBObject classes to the basic MongoDB interpretation. Without respect to your actual "query" document the "update" document part of your statement should be:
BasicDBObject update = new BasicDBObject("$set", new BasicDBObject("name","john")
.append("$currentDate", new BasicDBObject("birthrhday",true))
;
Which will indeed use the "server time" at the point of "update insertion" or "modification" with respect to the $currentDate modifier as used.
Just to be clear here, you don't use the .insert() method but an "upsert"operation with .insert(). The "query" and "update" syntax applies. Also see the $setOnInsert operator for specifically not modifying existing documents.
You can also use aggregation variable "$$NOW" if you are using an aggregation pipeline with update method.
MongoClient mongoClient = new MongoClient();
DB sampleDB = mongoClient.getDB("sampleDB");
BasicDBObject update =
new BasicDBObject("$set", new BasicDBObject("name","john")
.append("birthday", new BsonString("$$NOW")));
sampleDB.getCollection("col1").updateOne(query, List.of(update));
You can also use "$$NOW" with aggregation operators such as $add, $subtract, and many more, to compute more specific values (including dates) on the database side.
If you want to pass the Application Server's time instead of Database time, use the following code to send the current time. You should decide whether to use this in case if the Application Server time differs from Database Server time.
new BsonDateTime(Instant.now().toEpochMilli())
Sample Code:
MongoClient mongoClient = new MongoClient();
DB sampleDB = mongoClient.getDB("sampleDB");
BasicDBObject update =
new BasicDBObject("$set", new BasicDBObject("name","john")
.append("birthday", new BsonDateTime(Instant.now().toEpochMilli())));
sampleDB.getCollection("col1").updateOne(query, update);

how do i search for an entry in mongodb database using java in netbeans?

I have made a database in Mongodb and a collection with a few entries.I want to search for an entry using Java and also display it. I'm using Netbeans as my IDE. I tried searching all over the internet but couldn't find anything relevant. I'm new to Java and Mongodb.
DBObject result = new Mongo().getDb("yourDatabaseName").getCollection("yourTableName").findOne(new BasicDBObject("id", id), new BasicDBObject("specialColumn", 1));
return result.get("specialColumn")
This example will search for the field "specialColumn" in the collection "yourTableName" with the id "id"!
There are more methods provided like .find(), where you can process with a DBCursor to check the results!
http://docs.mongodb.org/manual/tutorial/query-documents/

Categories