Duplicate the documents in same collection in mongo - mongodb

Is there a way to duplicate the records in a collection into the same collection ? I am trying to generate lots of records and hence this is needed.

If you just want to duplicate easy way is like below
db.col1.find({},{_id:0}).forEach(function(doc){db.col1.save(doc)});

A quick but maybe not the most efficient way to do that could be:
Get all the documents of the collection
For each one re-write the ObjectId with a new value
Insert the modified document inside the collection
With mongo shell you could do that using the forEach as follows:
db.getCollection('YOUR_COLLECTION').find({}).forEach(
function(doc){
doc._id = new ObjectId();
db.getCollection('YOUR_COLLECTION').insert(doc);
}
)
This way, each time you run this query, all the documents in the collection are duplicated.

Related

Is there a way to quickly check every table in a mongodb database with the column "title"?

Is there a way to quickly check every table in a mongodb database with the column "title"? I need to identify every table or rather collection where there's a column with the word "title", is there a way to do this using a mongodb query?
In Mongo there is no straight forward query to check all collections and fields. Instead, you can get a list of all collections using getCollectionInfos and then query each collection to see if there exists the field that you are looking for.
db.getCollectionInfos().forEach(function(c){
result = db.getCollection(c.name).findOne({"title":{$exists:true}});
if(result != null){
print(c.name);
}
}
);
This will not look for nested documents, though.

Remove all documents from each collection with the matched query

I want to remove all documents with the matched query in mongodb. which means there will be a field "head" in all collections. i want to remove all documents in each collection with head is matched with id : 128643 using single query. How can i do that with mongoose?
I’d recommend spending time in the mongoose documentation, it’s pretty easy to find there...
The command you’re looking for is Model.deleteMany()
So in your case, it would be Model.deleteMany({ id: 128643 });

Query documents, update it and return it back to MongoDB

In my MongoDB 3.2 based application I want to perform the documents processing. In order to avoid the repeated processing on the same document I want to update its flag and update this document in the database.
The possible approach is:
Query the data: FindIterable<Document> documents = db.collection.find(query);.
Perform some business logic on these documents.
Iterate over the documents, update each document and store it in a new collection.
Push the new collection to the database with db.collection.updateMany();.
Theoretically, this approach should work but I'm not sure that it is the optimal scenario.
Is there any way in MongoDB Java API to perform the followings two operations:
to query documents (to get them from the DB and to pass to the separate method);
to update them and then store the updated version in DB;
in a more elegant way comparing to the proposed above approach?
You can update document inplace using update:
db.collection.update(
{query},
{update},
{multi:true}
);
It will iterate over all documents in the collection which match the query and updated fields specified in the update.
EDIT:
To apply some business logic to individual documents you can iterate over matching documents as following:
db.collection.find({query}).forEach(
function (doc) {
// your logic business
if (doc.question == "Great Question of Life") {
doc.answer = 42;
}
db.collection.save(doc);
}
)

Find the collection name from document._id in meteor (mongodb)

From the looks of the syntax for handling mongodb related things in meteor it seems that you always need to know the collection's name to update, insert, remove or anything to the document.
What I am wondering is if it's possible to get the collection's name from the _id field of a document in meteor.
Meaning if you have a document with the _id equal to TNTco3bHzoSFMXKJT. Now knowing the _id of the document you want to find which collection the document is located in. Is this possible through meteor's implementation of mongodb or vanilla mongodb?
As taken from the official docs:
idGeneration String
The method of generating the _id fields of new documents in this collection. Possible values:
'STRING': random strings
'MONGO': random Meteor.Collection.ObjectID values
The default id generation technique is 'STRING'.
Your best option would be to insert records within a pseudo transaction where the second step is to take the id and collection name to feed it into a reference collection. Then, you can do your lookups from that.
It would be pretty costly, though to construct your find's but might be a pattern worthwhile exploring if you are building an app where your users will be creating arbitrary data patterns.
You could accomplish this by doing a findOne on all of the collections:
var collectionById = function(id) {
return _.find(_.keys(this), function(name) {
if (this[name] instanceof Meteor.Collection) {
if (this[name].findOne(id)) {
return true;
}
}
});
};
I tested this on both the client and the server and it seemed to work when run in the global context.

Mongo find unique results

What's the easiest way to get all the documents from a collection that are unique based on a single field.
I know I can use db.collections.distrinct to get an array of all the distinct values of a field, but I want to get the first (or really any one) document for every distinct value of one field.
e.g. if the database contained:
{number:1, data:'Test 1'}
{number:1, data:'This is something else'}
{number:2, data:'I'm bad at examples'}
{number:3, data:'I guess there\'s room for one more'}
it would return (based on number being unique:
{number:1, data:'Test 1'}
{number:2, data:'I'm bad at examples'}
{number:3, data:'I guess there\'s room for one more'}
Edit: I should add that the server is running Mongo 2.0.8 so no aggregation and there's more results than group will support.
Update to 2.4 and use aggregation :)
When you really need to stick to the old version of MongoDB due to too much red tape involved, you could use MapReduce.
In MapReduce, the map function transforms each document of the collection into a new document and a distinctive key. The reduce function is used to merge documents with the same distincitve key into one.
Your map function would emit your documents as-is and with the number-field as unique key. It would look like this:
var mapFunction = function(document) {
emit(document.number, document);
}
Your reduce-function receives arrays of documents with the same key, and is supposed to somehow turn them into one document. In this case it would just discard all but the first document with the same key:
var reduceFunction = function(key, documents) {
return documents[0];
}
Unfortunately, MapReduce has some problems. It can't use indexes, so at least two javascript functions are executed for every single document in the collections (it can be limited by pre-excluding some documents with the query-argument to the mapReduce command). When you have a large collection, this can take a while. You also can't fully control how the docments created by MapReduce are formed. They always have two fields, _id with the key and value with the document you returned for the key.
MapReduce is also hard to debug an troubleshoot.
tl;dr: Update to 2.4