How to create a collection in MongoDB using SPRING data - mongodb

Am using Spring-Data-Mongo to access do CRUD operations on my mongo database. I execute the below line
DB db = mongoTemplate.getDb()
When am in debug mode I can see that db._collections properties has 4 values (collections that I inserted). But when I query for
db.getCollectionNames()
I get zero collections back. Why is that? Same is also true when I do
db.getCollection("collectionName")
But I know the collections do exists because when I do something like
mongoTemplate.createCollection("collectionName");
I get an exception saying that collection already exists. Can anyone please explain what I might be missing

MongoTemplate provides a few methods for managing collections. The following example demonstrates some of the methods:
DBCollection collection = null;
if (!mongoTemplate.getCollectionNames().contains("collectionName")) {
collection = mongoTemplate.createCollection("collectionName");
}
mongoTemplate.dropCollection("collectionName");
In the above, getCollectionNames() returns a set of collection names and dropCollection() drops the collection.

Use MongoClient, MongoDatabase, and MongoIterable of com.mongodb.client and com.mongodb package.
MongoClient client = MongoClient(<host>, port);
MongoDatabase db = client.getDatabase(<Name of the database>);
MongoIterable<String> = db.listCollectionNames();
And now you can iterate over all the names of the collections.
Additionally, you even can use MongoCollection class to get the Document from the specified collection. The getCollection() will create collection if not present.
MongoCollection<Document> collection = db.getCollection(<Collection name>);

Related

Delete all documents in a collection with Springdata mongo Query

I want to implement a delete method which deletes all the documents in a collection. I am using mongo db with Spring Data.This could be done using db.myCollection.remove({}) in Mongo shell. But I want to write a method in my data access layer to do this.I am not using MongodbTemplate in my Dao class. I want to know how can I do this with Query.
Query query = new Query();
Could anybody please tell me how can I do it.
You can use MongoTemplate directly
mongoTemplate.remove(new Query(), collectionName);
Use MongoRepository's deleteAll(). Utilizes mongoTemplate behind the scene to call the remove method.
From calling method someRepository.deleteAll()
Drop collection may be efficient as other answer has noted. For that you will need to use MongoTemplate directly and call dropCollection with entity class or collection name.
You can drop the collection and create it again:
mongoTemplate.dropCollection("collectionName");
mongoTemplate.createCollection("collectionName");
You'd better drop the entire collection (if possible) than deleting all documents. For performance and allocation sake.
You can try something such as:
MongoClient mongoClient = new MongoClient(new ServerAddress("localhost", 27017));
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection collection = db.getCollection("test_collection");
collection.drop();
If you do want to delete all (I think), instead of:
collection.drop();
use:
Bson filter = new Document();
collection.deleteMany(filter);
Query is part of spring-data-mongodb, if you can't use a MongoTemplate, probably Query is irrelevant as well.
If you have considerable changes in schema, better is to drop the collection.
MongoTemplate.dropCollection(collectionName).
But the requirement is to delete all documents you have use
MongoTemplate.remove(new Query(), collectionName)or
CrudRepository.deleteAll()
If all collections are to be deleted, this could also be done:
mongoTemplate.collectionNames
.forEach { mongoTemplate.dropCollection(it) }

MongoDB java client's WriteConcern doesn't work

I am a newbie to use MongoDB. I just imported the latest MongoDB java client via Maven:
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.2.2</version>
</dependency>
And then I wrote a very simple program to test the insert operation.
//I use a replicaset
MongoClient mongoClient = new MongoClient(
Arrays.asList(new ServerAddress("10.12.16.136", 29017),
new ServerAddress("10.12.16.136", 29018),
new ServerAddress("10.12.16.136", 29019)));
//I just want to write and ignore any database errors. (This does not work)
mongoClient.setWriteConcern(WriteConcern.UNACKNOWLEDGED);
//Get database and collection
MongoDatabase database = mongoClient.getDatabase("test");
MongoCollection<Document> collection = database.getCollection("realtime");
//This does not work too.
collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED);
//Make a simple object to insert. I already have a document with the same _id in the database and I don't want to see the exception via the WriteConcern operation.
Document doc = Document("longitude", longitude)
.append("latitude", latitude)
.append("velocity", velocity)
.append("soc", soc)
.append("_id", 12345678);
//WriteConcern.UNACKNOWLEDGED doesn't work. An exception will be raised.
collection.insertOne(doc);
How can I do the right thing?
That's because collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED); generates a new MongoCollection object with a different write concern which you never use:
/**
* Create a new MongoCollection instance with a different write concern.
*
* #param writeConcern the new {#link com.mongodb.WriteConcern} for the collection
* #return a new MongoCollection instance with the different writeConcern
*/
MongoCollection withWriteConcern(WriteConcern writeConcern);
The following code:
MongoCollection<Document> dup = collection.withWriteConcern(WriteConcern.UNACKNOWLEDGED);
...
dup.insertOne(doc);
should work, i.e. no error raised.
As for the MongoClient level write concern which is not propagated to the database:
public MongoDatabase getDatabase(final String databaseName) {
MongoClientOptions clientOptions = getMongoClientOptions();
return new MongoDatabaseImpl(databaseName, clientOptions.getCodecRegistry(), clientOptions.getReadPreference(),
clientOptions.getWriteConcern(), createOperationExecutor());
}
As you can see, the write concern is taken from MongoClientOptions ignoring the parameter value passed to mongoClient.setWriteConcern() method, which may be a bug.
So, to set a global write concern properly, you will have to create an instance of MongoClientOptions:
MongoClientOptions options = MongoClientOptions
.builder()
.writeConcern(WriteConcern.UNACKNOWLEDGED)
.build();
and pass it to the MongoClient constructor.
I had got this exception, when on empty collection was already present in MongoDB, and i was trying to create one more same collection by mistake, so when i deleted the existing collection and then did a post API, then it worked fine for me..
So better first drop your existing collection and then try to call any CRUD API..
if there is one Java entity with Collection ( name="STUDENT" ) , and you are again trying to create one collection with name student, this error comes

Determine whether collection in MongoDB exists in Python

I want to know whether collections of specific names exists in the MongoDB. How can I achieve this programmatically in Python. On searching about the same, I got to know how to do that from MongoDB shell but nothing useful for doing the same in Python.
You can use the method to retrieve and check if your collection exists or not from the comment given by the #Alex like this:
Method 1:
import pymongo
connection = pymongo.MongoClient('localhost', 27017) # Connect to mongodb
db = connection['test_db']
list_of_collections = db.list_collection_names() # Return a list of collections in 'test_db'
print("posts" in list_of_collections) # Check if collection "posts" exists in db (test_db)
Or, you can validate a collection with validate_collection() (documentation) This returns an error (pymongo.errors.OperationFailure) if the collection doesn't exist. With this method, you can also catch that exception and do whatever you want.
Method 2:
import pymongo
connection = pymongo.MongoClient('localhost', 27017) # Connect to mongodb
db = connection['test_db']
try:
db.validate_collection("random_collection_name") # Try to validate a collection
except pymongo.errors.OperationFailure: # If the collection doesn't exist
print("This collection doesn't exist")

What do the PyMongo docs mean by "sub-collection"?

This page in the documentation says you can access a collection using c[name] or c.name, where c is a Collection, but what exactly does a sub-collection mean? I couldn't find any use of the term in the mongodb docs.
What I'm assuming, is that it gets the value of each document at key name, wihtin the collection, and represents that as its own collection. Is this the case?
A subcollection is just a naming convention of using . in a collection name as a way to organize your collection names.
So with the following code:
client = pymongo.MongoClient()
db = client['mydb']
coll = db['test']
subcoll = coll['subtest']
subcoll is a collection with a name of test.subtest. There's no defined relationship between test and test.subtest, it's just naming.

MongoDB Java Driver creating Database and Collection

i was testing how to create database and collection mongo java driver.
MongoClient client = new MongoClient("localhost",27017);
DB db = client.getDB("ow");
DBCollection collection = db.getCollection("documents");
collection.save(new BasicDBObject("_id",1));
collection.remove(new BasicDBObject("_id",1));
boolean result = db.collectionExists("documents");
assertTrue(result);
assertNotNull(collection);
client.close();
I would prefer to use createCollection method on the DB object, but found that it does not create database / collection unless the first document is inserted.
My question is is this understanding correct ? Is above code correct was of creating collection or database.
prefer to use createCollection method on the DB object, but found that it does not create database / collection unless the first
document is inserted.
MongoDB creates a collection implicitly when the first document is saved into a collection. The createCollection() method explicitly creates a collection only and only if an options object is passed to it as an argument.
Now this makes sense. The options parameter can take in one or more arguments to decide the characteristics of the collection we want to create such as capped,autoIndexId,size,usePowerOf2Sizes,max no. of documents.
If we do not specify any of these options, the default behavior would take precedence, i.e create a collection lazily whenever the first insert is made, with default settings.
So if we want a collection whose characteristics we are going to define, then we can pass these characteristics as a DBObject to the createCollections() method and our collection would be created. Below is an example of how to pass the options.
BasicDBObject options = new BasicDBObject();
options.put("size", 12121212);
db.createCollection("hello", options);
Is above code correct was of creating collection or database.
Yes. It allows mongodb to apply the default configuration for your collection. Unless you want to set the
max,size,autoIndexId,capped,usePowerOf2Sizes properties for your new collection, this is fine.
Refer: http://docs.mongodb.org/manual/reference/method/db.createCollection/