How to overwrite docs from one collection to other collection in mongodb - mongodb

I have docs in collection c1, and update_dt. I want to insert all these docs from c1 to collection c2. It might be possible some docs already exists in c2 but still I want to insert updated docs to collection c2.
e.g-
collection c1-
doc1- { _id : 100, update_dt : "2015-10-29T15:45:00.000Z", Name: "Leo" }
Collection c2-
doc1- { _id : 100, update_dt : "2015-10-10T15:45:00.000Z" }.
And I want to overwrite doc1 of collection c1 to doc1 of collection c2.
I tried but shows duplicate key error as _id field can't be same.
I want to automate this, will really appreciate your help.

Related

Find Modify and Insert into the Same Collection of MongoDB

Can any one help me with below case in MongoDB:
find documents with a condition from Collection A. (lets say we got
2 documents)
Modify those 2 documents and then insert into Same collection A , with out disturbing original 2 documents.
Aggregation wont support merge into same collection, I got it through simple javascript, but we need in MapReduce.
Below is my Simple Script:
db.col1.find({
"field1": "value"
}).forEach(function(d1) {
d1.f2 = NumberInt(d1.f2 / 10);
db.col1.save(d1)
})
Before saving the modified document d1, change its _id with a new ObjectId(), this will insert new d1 instead of updating the existing one:
db.col1.find({"field1" : "value"}).forEach(function(d1)
{
d1.f2 = NumberInt(d1.f2/10);
d1._id = ObjectId();
db.col1.save(d1);
})

Optimising queries in mongodb

I am working on optimising my queries in mongodb.
In normal sql query there is an order in which where clauses are applied. For e.g. select * from employees where department="dept1" and floor=2 and sex="male", here first department="dept1" is applied, then floor=2 is applied and lastly sex="male".
I was wondering does it happen in a similar way in mongodb.
E.g.
DbObject search = new BasicDbObject("department", "dept1").put("floor",2).put("sex", "male");
here which match clause will be applied first or infact does mongo work in this manner at all.
This question basically arises from my background with SQL databases.
Please help.
If there are no indexes we have to scan the full collection (collection scan) in order to find the required documents. In your case if you want to apply with order [department, floor and sex] you should create this compound index:
db.employees.createIndex( { "department": 1, "floor": 1, "sex" : 1 } )
As documentation: https://docs.mongodb.org/manual/core/index-compound/
db.products.createIndex( { "item": 1, "stock": 1 } )
The order of the fields in a compound index is very important. In the
previous example, the index will contain references to documents
sorted first by the values of the item field and, within each value of
the item field, sorted by values of the stock field.

MongoDB select subdocument with aggregation function

I have a mongo DB collection that looks something like this:
{
{
_id: objectId('aabbccddeeff'),
objectName: 'MyFirstObject',
objectLength: 0xDEADBEEF,
objectSource: 'Source1',
accessCounter: {
'firstLocationCode' : 283,
'secondLocationCode' : 543,
'ThirdLocationCode' : 564,
'FourthLocationCode' : 12,
}
}
...
}
Now, assuming that this is not the only record in the collection and that most/all of the documents contain the accessCounter subdocument/field how will I go with selecting the x first documents where I have the most access from a specific location.
A sample "query" will be something like:
"Select the first 10 documents From myCollection where the accessCounter.firstLocationCode are the highest"
So a sample result will be X documents where the accessCounter. will be the greatest is the database.
Thank your for taking the time to read my question.
No need for an aggregation, that is a basic query:
db.collection.find().sort({"accessCounter.firstLocation":-1}).limit(10)
In order to speed this up, you should create a subdocument index on accessCounter first:
db.collection.ensureIndex({'accessCounter':-1})
assuming the you want to do the same query for all locations. In case you only want to query firstLocation, create the index on accessCounter.firstLocation.
You can speed this up further in case you only need the accessCounter value by making this a so called covered query, a query of which the values to return come from the index itself. For example, when you have the subdocument indexed and you query for the top secondLocations, you should be able to do a covered query with:
db.collection.find({},{_id:0,"accessCounter.secondLocation":1})
.sort("accessCounter.secondLocation":-1).limit(10)
which translates to "Get all documents ('{}'), don't return the _id field as you do by default ('_id:0'), get only the 'accessCounter.secondLocation' field ('accessCounter.secondLocation:1'). Sort the returned values in descending order and give me the first ten."

Finding if the document is unique

I am querying 3 collections in MongoDB and then creating a new document by taking some fields from the documents of the 3 separate collections. For example: I am taking field 'A' from first collection, field 'B' from second and field 'C' from third.
Using them i am creating a json document like
var uploadDoc = {
'A' : <value of A>,
'B' : <value of B>,
'C' : <value of C>,
}
This uploadDoc is being uploaded to another collection.
Question: I wish to upload only distinct values of uploadDoc. By default MongoDB gives each uploadDoc a unique id. How do I insert uplodDocs to the collection only when another document with the same A, B and C values hasn't been inserted before?
I am using javascript to query the collections and create docs.
Two ways are simple:
use "upserts"
db.collection.update(uploadDoc,uploadDoc,{ "upsert": true })
Use a unique index
db.collection.ensureIndex({ "A": 1, "B": 1, "C": 1 },{ "unique": true });
db.collection.insert(uploadDoc); // Same thing fails :(
Both work. Choose one.
You should use Unique Indexes: doc
You shouldn't use upsert without unique indexes:
To avoid inserting the same document more than once, only use upsert: true if the query field is uniquely indexed.
because
Consider when multiple clients issue the following update with an upsert parameter at the same time:
[cut]
If all update() operations complete the query portion before any client successfully inserts data, and there is no unique index on the name field, then each update operation may result in an insert.
from here

Mongodb Indexing suggestions

All,
I have a mangodb collection with below fields.
_ID
Title
Description
Tags , array
I have created 2 index on _id and tags field. I have created index for people to search the content with help of keywords.
I have created the index with tags:-1 to show the latest inserted records to show first. But even after that it is showing in the ascending order of _id.
How to create the index on tags field to show the last inserted to show first at the same time it should allow me to search on tags field faster .
If the _id field is the default ObjectId which reflects the insertion order, and you want to query all the documents with a specific Tags by descending insertion order, you can use the query as below:
find({ Tags : $value }).sort({ _id : -1 })
For this query, you can create a compound index on { Tags : 1, _id : -1 }. All the documents with the same Tags will be sorted in descending insertion order and this index should work well for this query.
Please note that if you are doing range query on Tags, like:
find({ Tags : { $in : [ $value1, $value2 ] }}).sort({ _id : -1 })
find({ Tags : { $gt : $value}}).sort({ _id : -1})
It wouldn’t be able to use the index to sort the result documents, and will need to sort the results in memory. You can run the query with .explain(true) to check the query plan. If scanAndOrder is true, it means the query cannot use the order of documents in the index for returning sorted results.
There are also some documents and blogs relate to indexes and that I'd recommend reading:
http://docs.mongodb.org/manual/tutorial/sort-results-with-indexes/
http://emptysqua.re/blog/optimizing-mongodb-compound-indexes/
http://blog.mongolab.com/2012/06/cardinal-ins/