I have the following DB:
{
"_id" : ObjectId("556da79a77f9f7465943ff93"),
"guid" : "a12345",
"update_day" : "12:05:10 02.06.15"
}
{
"_id" : ObjectId("556dc4509a0a6a002f97e972"),
"guid" : "bbbb",
"update_day" : "15:03:10 02.06.15"
"__v" : 0
}
{
"_id" : ObjectId("556dc470e57836242f5519eb"),
"guid" : "bbbb",
"update_day" : "15:03:10 02.06.15"
"__v" : 0
}
{
"_id" : ObjectId("556dc47c7e882d3c2fe9e0fd"),
"guid" : "bbbb",
"update_day" : "15:03:10 02.06.15"
"__v" : 0
}
I want to set the guid to be unique, so no to duplicate is possible (Like primary key in MYSQL). So the DB will look like this:
{
"_id" : ObjectId("556da79a77f9f7465943ff93"),
"guid" : "a12345",
"update_day" : "12:05:10 02.06.15"
}
{
"_id" : ObjectId("556dc4509a0a6a002f97e972"),
"guid" : "bbbb",
"update_day" : "15:03:10 02.06.15"
"__v" : 0
}
and when I will insert another "guid":"bbbb" (with the save command), it will fails.
While declaring schema in mongoose, do this
guid : { type : String, unique : true}
AND if you want mongodb to create the guid on its own (like _id) then do this
guid : { type : String, index : { unique : true} }
First, you have to deal with the current state of your MongoDB collection and delete all the duplicated documents.
One thing is sure : you won't be able to create the unique index with duplicates in your collection and dropDupes is now deprecated since the version 2.7.5 so you can't use it. By the way, it was removed because it was almost impossible to predict which document would be deleted in the process.
Two possible solutions :
Create a new collection. Create the unique index on this new collection and run a batch to copy all the documents from the old collection to the new one and make sure you ignore duplicated key error during the process.
Deal with it in your own collection manually :
make sure you won't insert more duplicated documents in your code,
run a batch on your collection to delete the duplicates (and make sure you keep the good one if they are not completely identical),
then add the unique index.
I would declare my guid like so in mongoose :
guid : { type : String, unique : true}
Related
I have notification click table like this:
{
"_id" : ObjectId("5d00d4e1d720cc4cb1b24566"),
"createdOn" : ISODate("2019-06-12T10:33:05.866Z"),
"notification_center_id" : [
ObjectId("5c59343523f05e2ff13938d6")
],
"user_id" : ObjectId("5bc5dc03f6d24d29077dd362"),
"__v" : 0
}
I want to check if user_id "5bc5dc03f6d24d29077dd362" is already exists then added another notification_center_id in already exists record.
like this
{
"_id" : ObjectId("5d00d4e1d720cc4cb1b24566"),
"createdOn" : ISODate("2019-06-12T10:33:05.866Z"),
"notification_center_id" : [
ObjectId("5c59343523f05e2ff13938d6"),
ObjectId("5c5c4610c6d91403f38eda52")
],
"user_id" : ObjectId("5bc5dc03f6d24d29077dd362"),
"__v" : 0
}
I want query that first check user id exists if exists then added another notification record in notification_center_id field.
If user is not exists then I want add another record in collection
one more condition here, if notification_center_id is not inserted duplicate. if it's exist then not added.
Please help me.
db.getCollection('test').update(
{"user_id" : ObjectId("5bc5dc03f6d24d29077dd362")},
{"$push" : {"notification_center_id" : new ObjectId()}}
)
In your question, you have not mentioned what to do if user_id doesn't exist. So doing nothing in that case.
After your comment
db.getCollection('test').update(
{"user_id" : ObjectId("5c59343523f05e2ff13938d6")},
{
"$push" : {"notification_center_id" : new ObjectId()},
"$setOnInsert" : {"createdOn" : new ISODate(), "__v" : 0}
},
{"upsert" : true}
)
$addToSet update operator is used to append an element to an array and preserves uniqueness of values into an array.
db.notifications.update({"_id" : ObjectId("5d00d4e1d720cc4cb1b24566")}
, { $addToSet: { notification_center_id: new ObjectId() } })
> db.orders.find({})
{ "_id" : ObjectId("5b78b933d62e262ddb055509"), "user_id" : "5b16d96a74be42566844e0b4", "game_id" : "5b11c56c6c71dc44976fba55", "seats" : { "_id" : ObjectId("5b78b933d62e262ddb05550a") }, "__v" : 0 }
{ "_id" : ObjectId("5bb135638625d21c0883fe1d"), "user_id" : "5b16d96a74be42566844e0b4", "game_id" : "5b11c56c6c71dc44976fba61", "seats" : { "_id" : ObjectId("5bb135638625d21c0883fe1e") }, "__v" : 0 }
The above is the output of find command on the orders stored in my Mongo Instance.
seats is an array of objects embedded in the orders schema. How can I view and fetch the array stored in Object seats?
seats is a cross-reference field which contains the ObjectIds to anther collection.
Are you using Mongoose? If so you need to use the populate method to fill in the objects on find etc.
I have id of person ObjectId("5650e94b2e62c5fbfa0ebdd1"). How get name of its leader with one query?
/* 1 */
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd1"),
"login" : "Todd",
"fullname" : "Eva Bailey",
"leader" : ObjectId("5650e94b2e62c5fbfa0ebdd2"),
"group" : ObjectId("5650e94b2e62c5fbfa0ebdbf")
}
/* 2 */
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd2"),
"login" : "Kennedy",
"fullname" : "Oscar Stokes",
"leader" : null,
"group" : ObjectId("5650e94b2e62c5fbfa0ebdbf")
}
MongoDB is non relational database and does not support joins as opposed to other relational DB which defines relationship through reference keys across tables in database.
Instead of defining references of documents across collections in MongoDB you can utilize embedded document feature of MongoDB.
Embedded documents are easy and fast
Example :
{
"_id" : ObjectId("5650e94b2e62c5fbfa0ebdd1"),
"login" : "Todd",
"fullname" : "Eva Bailey",
"leader" :
{
"name":"Tony Smith"
},
"group" : {
}
}
I'm trying to add a username field to documents in a 'users' collection, and I'd like it to be a unique index. (So far, we've been using email addresses for login but we'd like to add a username field as well.) However, running db.users.ensureIndex({username:1},{unique:true}) fails because mongo considers all the unset usernames to be duplicates and therefore not unique. Anybody know how to get around this?
Show the current users and username if they have one:
> db.users.find({},{_id:0,display_name:1,username:1})
{ "display_name" : "james" }
{ "display_name" : "sammy", "username" : "sammy" }
{ "display_name" : "patrick" }
Attempt to make the 'username' field a unique index:
> db.users.ensureIndex({username:1},{unique:true})
{
"err" : "E11000 duplicate key error index: blend-db1.users.$username_1 dup key: { : null }",
"code" : 11000,
"n" : 0,
"connectionId" : 272,
"ok" : 1
}
It doesn't work because both james and sammy have username:null.
Let's set patrick's username to 'patrick' to eliminate the duplicate null value.
> db.users.update({display_name: 'patrick'}, { $set: {username: 'patrick'}});
> db.users.ensureIndex({username:1},{unique:true})
> db.users.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "blend-db1.users",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"username" : 1
},
"unique" : true,
"ns" : "blend-db1.users",
"name" : "username_1"
}
]
Now it works!
To clarify the question, what I'd like is to be able to make username a unique index without having to worry about all the documents that have username still set to null.
Try creating a unique sparse index:
db.users.ensureIndex({username:1},{unique:true,sparse:true})
As per the docs:
You can combine the sparse index option with the unique indexes option
so that mongod will reject documents that have duplicate values for a
field, but that ignore documents that do not have the key.
Although this only works for documents which don't have the field, as opposed to documents that do have the field, but where the field has a null value.
When I call ensureIndex from the mongo shell on a collection for a compound index an _id field of type ObjectId is auto-generated in the index object.
> db.system.indexes.find();
{ "name" : "_id_", "ns" : "database.coll", "key" : { "_id" : 1 } }
{ "_id" : ObjectId("4ea78d66413e9b6a64c3e941"), "ns" : "database.coll", "key" : { "a.b" : 1, "a.c" : 1 }, "name" : "a.b_1_a.c_1" }
This makes intuitive sense as all documents in a collection need an _id field (even system.indexes, right?), but when I check the indexes generated by morphia's ensureIndex call for the same collection *there is no _id property*.
Looking at morphia's source code, it's clear that it's calling the same code that the shell uses, but for some reason (whether it's the fact that I'm creating a compound index or indexing an Embedded document or both) they produce different results. Can anyone explain this behavior to me?
Not exactly sure how you managed to get an _id field in the indexes collection but both shell and Morphia originated ensureIndex calls for compound indexes do not put an _id field in the index object :
> db.test.ensureIndex({'a.b':1, 'a.c':1})
> db.system.indexes.find({})
{ "v" : 1, "key" : { "_id" : 1 }, "ns" : "test.test", "name" : "_id_" }
{ "v" : 1, "key" : { "a.b" : 1, "a.c" : 1 }, "ns" : "test.test", "name" : "a.b_1_a.c_1" }
>
Upgrade to 2.x if you're running an older version to avoid running into now resolved issues. And judging from your output you are running 1.8 or earlier.