I am newbie to mongodb. May I know how to avoid duplicate entries. In relational tables, we use primary key to avoid it. May I know how to specify it in Mongodb using java?
7 Answers
Use an index with the {unique:true}
option.
// everyone's username must be unique:
db.users.createIndex({email:1},{unique:true});
You can also do this across multiple fields. See this section in the docs for more details and examples.
A unique index ensures that the indexed fields do not store duplicate values; i.e. enforces uniqueness for the indexed fields. By default, MongoDB creates a unique index on the _id field during the creation of a collection.
If you wish for null
values to be ignored from the unique key, then you have to also make the index sparse (see here), by also adding the sparse
option:
// everyone's username must be unique,
//but there can be multiple users with no email field or a null email:
db.users.createIndex({email:1},{unique:true, sparse:true});
If you want to create the index using the MongoDB Java Driver. Try:
Document keys = new Document("email", 1);
collection.createIndex(keys, new IndexOptions().unique(true));

- 14,170
- 5
- 51
- 74
-
Note: `null` and none existant also counts as unique values so if you have a table of users with some deleted and by law you remove their data but keep their row for future deletion you will have problems with unique indexes. I guess it's down to need really. – Sammaye Aug 30 '12 at 07:18
-
2@Sammaye: You can use [sparse indexes](http://www.mongodb.org/display/DOCS/Indexes#Indexes-sparse%3Atrue) to resolve the issue with null/missing fields. – Stennie Aug 30 '12 at 07:25
-
+1 It's mentioned in the docs here, last paragraph for unique indexes: http://docs.mongodb.org/manual/core/indexes/#unique-index – theon Aug 30 '12 at 07:29
-
@Stennie Fair enough I must have missed that addition – Sammaye Aug 30 '12 at 08:10
-
I don't think this works if you use BasicDBObject(...).append(...). The unique key/value need to be in a separate DBObject. The code above will attempt to create an index over keys "email" and "unique". – viking Apr 15 '15 at 16:10
-
This approach seems to be from a relational mindset and seems to contradict the mongodb notion of an unstructured collection of docs. (I realize it's from their own docs) Setting a unique index on a key will indeed ensure that all the documents are unique, but potentially prevents entire classes of unique documents from being inserted into the collection. Such as documents with the same value(s) for the indexed key(s), but different values for other, non-indexed keys. Is there a way to avoid duplicate docs in mongo that doesn't impose any structure on the docs in the collection? – Allen Aug 08 '15 at 20:56
-
This seems like the best solution I've been able to find: http://stackoverflow.com/a/24125275/1495011 – Allen Aug 09 '15 at 02:39
-
@viking You are right. I have fixed the Java example. – theon Feb 03 '16 at 22:06
-
Note: mongodb can't guarantee the uniqueness of secondary keys across shards! https://docs.mongodb.com/manual/reference/limits/#Unique-Indexes-in-Sharded-Collections – Andy Jul 18 '16 at 19:26
-
In Mongo 3.x `ensureIndex` is deprecated and should be discouraged: http://stackoverflow.com/a/30314946/846193 – Jinesh Aug 10 '16 at 18:35
-
1@Jinesh Thanks. Updated answer. – theon Aug 10 '16 at 19:25
This can be done using "_id" field although this use is discouraged. suppose you want the names to be unique, then you can put the names in "_id" column and as you might know "_id" column is unique for each entry.
BasicDBObject bdbo = new BasicDBObject("_id","amit");
Now , no other entry can have name as "amit" in the collection.This can be one of the way you are asking for.

- 2,519
- 3
- 18
- 23
As of Mongo's v3.0 Java driver, the code to create the index looks like:
public void createUniqueIndex() {
Document index = new Document("fieldName", 1);
MongoCollection<Document> collection = client.getDatabase("dbName").getCollection("CollectionName");
collection.createIndex(index, new IndexOptions().unique(true));
}
// And test to verify it works as expected
@Test
public void testIndex() {
MongoCollection<Document> collection = client.getDatabase("dbName").getCollection("CollectionName");
Document newDoc = new Document("fieldName", "duplicateValue");
collection.insertOne(newDoc);
// this will throw a MongoWriteException
try {
collection.insertOne(newDoc);
fail("Should have thrown a mongo write exception due to duplicate key");
} catch (MongoWriteException e) {
assertTrue(e.getMessage().contains("duplicate key"));
}
}

- 17,668
- 31
- 111
- 166
I am not a Java programmer however you can probably convert this over.
MongoDB by default does have a primary key known as the _id
you can use upsert()
or save()
on this key to prevent the document from being written twice like so:
var doc = {'name': 'sam'};
db.users.insert(doc); // doc will get an _id assigned to it
db.users.insert(doc); // Will fail since it already exists
This will stop immediately duplicates. As to multithread safe inserts under certain conditions: well, we would need to know more about your condition in that case.
I should add however that the _id
index is unqiue by default.

- 43,242
- 7
- 104
- 146
Theon solution didn't work for me, but this one did:
BasicDBObject query = new BasicDBObject(<fieldname>, 1);
collection.ensureIndex(query, <index_name>, true);

- 2,154
- 28
- 46
using pymongo it looks like:
mycol.create_index("id", unique=True)
where myCol is the collection in the DB
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import pymongo
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["mydatabase"]
mycol = mydb["customers"]
mycol.create_index("id", unique=True)
mydict = {"name": "xoce", "address": "Highway to hell 666", "id": 1}
x = mycol.insert_one(mydict)

- 47,427
- 17
- 69
- 97
Prevent mongoDB to save duplicate email
UserSchema.path('email').validate(async(email)=>{
const emailcount = await mongoose.models.User.countDocuments({email})
return !emailcount
}, 'Email already exits')
May this help ur question... worked for me.. use in user model. refer for explaination THANKS...

- 23
- 3