MongoDB - no duplicate entries for a key - mongodb

First of all, I've read this thread already and it didn't really help me on this particular problem. I'm also new to MongoDB.
I have a document in my db.songs collection:
{
"title" : "Ignorance"
"artist" : "Paramore"
"listeners" : ["John", "Bill", "Amber"]
}
I want enforce no duplicates on the users key, such that whenever I push "John" or an existing user, I get an error. Can I do this in mongo shell, and if so how can I configure my collection to employ this behavior?
Some example code that should give me a duplicate error (or some similar error):
db.songs.update({title:"Ignorance"}, {'$push':{listeners:"John"}})
Thank you in advance.

db.songs.ensureIndex({listeners:1},{unique:true})
Adding this index will not work. MongoDB will not ensure uniqueness within the subdocument using a unique index, instead it will do it collection wide. That is quite possibly why you are getting errors u8sing that.
Instead what you want to do is use something that will add the item to the "set" of items, that is where $addToSet ( http://docs.mongodb.org/manual/reference/operator/update/addToSet/ ) comes in.
Drop your index and use that operator and it should work.

Related

Mongo DB Unique Index - Partial filter expression on date field

We have a collection where few documents got duplicated due to an issue in the code. They are large in number (> 280K). Due to some user updates from the front end, these records have been updated. Now, these records cannot be removed as there is some transaction on these records. To avoid this, we are thinking of creating a unique index with a partial expression on the created date. However, this doesn't work. Need help on how to achieve this. As much as I could get in the documentation, a unique index with partial constraints will only consider the matching documents.
db.collection1.createIndex({"uniqueid":1},{"background":true, "unique":true, "partialFilterExperssion":{ "created_date":{"$gte":ISODate("2021-04-27T15:30:00Z")}}})
If you see here the created_date specified in the future as the time now is 2021-04-26T19:22:00, so ideally irrespective of the current data in the collection, based on the partialFilterExpression, this index should get created. However, this gives an error
{
"ok" : 0.0,
"errmsg" : "E11000 duplicate key error collection: lms.collection1 index: uniqueid_1 dup key: { : null }",
"code" : 11000
}
Why is this looking at existing data to create the index? Any help to understand the reason for the error will be appreciated here.
There is no issue with partial filter, partial filter is not considered as there is a spelling miss 'expression' part is misspelled. Once corrected, it worked like a charm. My bad.

create new collection in mongodb by adding index in system.indexes

when I attempt to insert new document manually in system.indexes collection in mongodb,new collection created.here goes the code
{
"v" : 1,
"key" : {
"code" : 1
},
"name" : "code_1",
"ns" : "mydb.collection"
}
where collection is my collection name which is not already present in database and mydb is my database name. Why new collection is getting created?
Is it possible to create collection by adding index manually in system.indexes.
Why are you asking us this? You already tried to add a new index to system.indexes. Has a new collection been created? If yes, then yes it is possible, if no, then not possible.
Is this a correct way?
How do you think? Have you read somewhere in documentation that in order to create a new collection you need to dance around and to create manually indexes in some system defined collection? Or may be it was written in documentation that db.createCollection(name, options) is what you should do or if you so desire you can just insert a document in a non existed collection and it will create it.
So why after all this one might think that the correct way is to do some manipulation with system.indexes?
As a complement to #Salvador Dali's answer strongly discouraging you to do modify system.index directly: if for some reason you really don't want/can't use createCollection, just remember this is a wrapper around the create command.
You can issue yourself such command to create a new collection:
db.runCommand( { create: "collection" } )
As about inserting an entry in system.indexes: from the doc:
Deprecated since version 3.0: Access this data using listIndexes.
The <database>.system.indexes collection lists all the indexes in the database.
By reading that it appears that system.indexes should be considered as read-only (its direct use is even deprecated since 3.0). The behavior you observed should be considered as unspecified. And so unreliable and subject to change without further notices.
If you really need to understand why it behave that way, maybe you should take a look at the source code or ask the question on the MongoDB developer mailing list. There you could have all the insights.

How to comapre all records of two collections in mongodb using mapreduce?

I have an use case in which I want to compare each record of two collections in mongodb and after comparing each record I need to find mismatch fields of all record.
Let us take an example, in collection1 I have one record as {id : 1, name : "bks"}
and in collection2 I have a record as {id : 1, name : "abc"}
When I compare above two records with same key, then field name is a mismatch field as name is different.
I am thinking to achieve this use case using mapreduce in mongodb. But I am facing some problems while accessing collection name in map function. When I tried to compare it in map function, I got error as : "errmsg" : "exception: ReferenceError: db is not defined near '
Can anyone give me some thoughts on how to compare records using mapreduce?
I might have helped you to read the documentation:
When upgrading to MongoDB 2.4, you will need to refactor your code if your map-reduce operations, group commands, or $where operator expressions include any global shell functions or properties that are no longer available, such as db.
So from your error fragment, you appear to be referencing db in order to access another collection. You cannot do that.
If indeed you are intending to "compare" items in one collection to those in another, then there is no other approach other than looping code:
db.collection.find().forEach(function(doc) {
var another = db.anothercollection.findOne({ "_id": doc._id });
// Code to compare
})
There is simply no concept of "joins" as such available to MongoDB, and operations such as mapReduce or aggregate or others strictly work with one collection only.
The exception is db.eval(), but as per all of strict warnings in the documentation, this is almost always a very bad idea.
Live with your comparison in looping code.

How can i change _id field in MongoDB Collection to User_id?

I am new user for MongoDB Database. In MongoDb whatever insert into some collection defaultly one field is added that is _id field.
For Example:
db.users.insert({"User_id":"1","User_Name":"xxx","Address":"yyyy"})
db.users.find()
It shows
{ "_id" : ObjectId("528475fc326b403f580d2eba"), "User_id" : "1", "User_Name" : "xxx",Address" : "yyyy" }
I don't need _id field and i want to replace that _id field to User_id with auto increment values.
Is it possible. Please help me. Thanks in advance.
_id field is really special in mongodb. This is your primary key there and there is no way you can have a document without it. Even if you are trying to insert the document without it, mongo will create it for you (as in your example). Moreover, you can not even modify _id field for you collection.
But you can create a document with your own _id. So if you want you can do db.users.insert({"_id":"1","User_Name":"xxx","Address":"yyyy"}) \\why exactly 1 is a string?
and remember that _id means user_id and also keep in mind that this _id should be unique
Keep in mind that mongodb is not like sql. It does not have autoincrement keys (by this I mean that it is not that creators did not know how to do it, but just that you can leave pretty much without it), but you can achieve create something that would resemble the same behaviour.
As for as I can understand your problem is that you want to use your mongoDB internal _id as your custom attribute. For example suppose the db contain the user Identity and having attributes like "_id , name , address ..." and you want to use this _id's value in your application as userId for external reference.
So as #SalvadorDali said _id field is really important in the mongoDB and you can not have a document without it. All you can do is let the db store the value by it's default _id but you can access outside using your own User_id by applying these two changes in your json file.
"properties": {
"userId":{
"type": "string",
"id":"true",
"index":"true",
"description": "unique id of identity"
}
}
now you store any unique value, it is stored in the db using default _id and outside you can have that value in userId field.
Correct me if i got your question wrong.

MongoDB C driver _id generation

I use mongo_insert() three times to insert my data in three different collections. The problem is that the "_id" field must be exactly the same in each of the collections, but I do not know how to (ideally) recover and reuse the "_id" field generated in my first mongo_insert...
Please, advice me how to do it.
Normally, you could have different field, like CustomId for your private needs, and leave _id for mongo generation.
But if you still need it to be exactly the same - there could be 2 variants:
1) setting custom generated _id do each doc.
2) Save first doc, then read it again, check it's _id and set it to the other docs.