I want to create an index so that my DB does not allow me to insert documents whose value for the key lema is already present in some document of the DB. I did this:
db.version()
3.0.14
> db.rae.ensureIndex({"lema":1, unique: true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 2,
"note" : "all indexes already exist",
"ok" : 1
}
> db.rae.insert({"lema":"a"})
WriteResult({ "nInserted" : 1 })
> db.rae.insert({"lema":"a"})
WriteResult({ "nInserted" : 1 })
> db.rae.insert({"lema":"a"})
WriteResult({ "nInserted" : 1 })
> db.rae.find()
{ "_id" : ObjectId("591a0ce372329f3162a314cc"), "lema" : "a" }
{ "_id" : ObjectId("591a0ce472329f3162a314cd"), "lema" : "a" }
{ "_id" : ObjectId("591a0ce572329f3162a314ce"), "lema" : "a" }
Clearly the DB is letting me insert documents whose values of lema are all a. How can I fix this? Thanks a lot
From Stennie's comment:
I should use createIndex instead of ensureIndex. Also I had a mistake, I should use db.rae.createIndex({"lema":1}, { unique: true}).
Related
I have a Mongodb collection with schema validation.
I executed db.correspondence.validate({full:true}) and received "nInvalidDocuments" : NumberLong(0)
I am able to insert a document but update is failing.
MongoDB Enterprise > db.correspondence.find({"correspondenceIdentifier": "ca4697e2-a40c-11ea-a632-0a0a6b0e0000"}).count()
8
MongoDB Enterprise > db.correspondence.insert({"correspondenceIdentifier": "ca4697e2-a40c-11ea-a632-0a0a6b0e0000",mdmContractIdentifier:'3334444444444444','name':'Vat'});
WriteResult({ "nInserted" : 1 })
MongoDB Enterprise > db.correspondence.find({"correspondenceIdentifier": "ca4697e2-a40c-11ea-a632-0a0a6b0e0000"}).count()
9
MongoDB Enterprise > db.correspondence.find({mdmContractIdentifier:'3334444444444444'}).count()
2
MongoDB Enterprise > db.correspondence.updateOne({"correspondenceIdentifier": "ca4697e2-a40c-11ea-a632-0a0a6b0e0000"},{$set:{mdmContractIdentifier:'3334444444444444'}});
2020-08-05T20:50:28.164-0400 E QUERY [thread1] **WriteError: Document failed validation** :
WriteError({
"index" : 0,
"code" : 121,
"errmsg" : "Document failed validation",
"op" : {
"q" : {
"correspondenceIdentifier" : "ca4697e2-a40c-11ea-a632-0a0a6b0e0000"
},
"u" : {
"$set" : {
"mdmContractIdentifier" : "3334444444444444"
}
},
"multi" : false,
"upsert" : false
}
})`
WriteError#src/mongo/shell/bulk_api.js:466:48
Bulk/mergeBatchResults#src/mongo/shell/bulk_api.js:846:49
Bulk/executeBatch#src/mongo/shell/bulk_api.js:910:13
Bulk/this.execute#src/mongo/shell/bulk_api.js:1154:21
DBCollection.prototype.updateOne#src/mongo/shell/crud_api.js:572:17
#(shell):1:1
This question already has answers here:
How do I update Array Elements matching criteria in a MongoDB document?
(2 answers)
Closed 4 years ago.
I have an object that looks like the following:
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : [
{
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafsdkjhc",
"sync" : false
},
{
"address" : "tz1MecudVJnFZN5FSrriu8ULz2d6dDTR7KaM",
"sync" : false
}
]
}
I am trying to update the sync field for specific object in the array. So for example if I update the sync field for the object at index 0 or address tz1SUgyRB8T5jXgXAwS33pgRHAKrafsdkjhc by doing the following it yields:
> db.delegate_list.update({"name":"delegateList"}, {$set:{"delegates.0.sync": true}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : [
{
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc",
"sync" : true
},
{
"address" : "tz1MecudVJnFZN5FSrriu8ULz2d6dDTR7KaM",
"sync" : false
}
]
}
It works as expected, but if I perform the same update command to switch back sync:false, it gives me a malformed object, while deleting the rest of the array:
> db.delegate_list.update({"name":"delegateList"}, {$set:{"delegates.0.sync": false}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : {
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc",
"sync" : true,
"0" : {
"sync" : false
}
}
}
You can update specific array item, if item match your case using $ operator
db.delegate_list.update({"delegates.address":"tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc"}, {$set:{"delegates.$.sync": false}})
It will update the sync filed which address is "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc"
only, and not going to add any extra field.
I Have a collection which has data like {m:1,n:3}
want to update this collection like {m:1,n:3,s:4}
where s= m+n in mongodb,
so for that, I tried
db.data.update({},{$set:{s:(m+n)});
but it doesn't work and I tried multiple things but still haven't a solution. How can I achieve this?
with aggregation you can $addFields and $out to a collection
db.col.aggregate([
{$addFields : {s : {$add:["$m", "$n"]}}},
{$out : "col"}
])
with $project for mongo version less than 3.4
db.col.aggregate([
{$project : {m:1, n:1, s : {$add:["$m", "$n"]}}},
{$out : "col"}
])
result
> db.col.drop()
true
> db.col.insert({m:2,n:4})
WriteResult({ "nInserted" : 1 })
> db.col.find()
{ "_id" : ObjectId("5a911efc6bb20635697c6b17"), "m" : 2, "n" : 4 }
> db.col.aggregate([{$addFields : {s : {$add:["$m", "$n"]}}},{$out : "col"}])
> db.col.find()
{ "_id" : ObjectId("5a911efc6bb20635697c6b17"), "m" : 2, "n" : 4, "s" : 6 }
>
I need to ensure combination of some fields to be unique , so i found out we can use indexes to achieve it , like :
db.user.ensureIndex({'fname':1,'lname':1},{unique:true})
However in my scenario i allow the user to add email or phone or even both . So how do i achieve the uniqueness in this case . I tried like setting 2 indexed like
db.user.ensureIndex({'fname':1,'lname':1,'email':1},{unique:true})
And
db.user.ensureIndex({'fname':1,'lname':1,'mobile':1},{unique:true})
this dint work when i try to add a document with email unique , like below
> db.user.insert({fname:'tony',lname:'stark',email:'aa#gmail.com'})
WriteResult({ "nInserted" : 1 })
> db.user.insert({fname:'tony',lname:'stark',email:'xyz#gmail.com'})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: temp.user.$fname_1_lname_1_mobile_1 dup key: { : \"tony\", : \"stark\", : null }"
}
})
I guess the error is because of the second index ,since both the inserts have null value for the mobile field . I then tried this
db.user.ensureIndex({'fname':1,'lname':1,'email':1,'mobile':1},{unique:true})
And that dint help ,is there any way to do this with mongodb or check the uniqueness with code otherwise .
Update
I need to ensure uniqueness in this case too :
db.user.insert({fname:'tony',lname:'stark',email:'abc#gmail.com'})
<<insert>>
db.user.insert({fname:'tony',lname:'stark',email:'abc#gmail.com',mobile:554545435})
<<dont insert>>
Update 2
Even Unique partial Index didn't help
> db.users.createIndex({ "fname": 1, "lname": 1, "email":1 },
... { unique: true, partialFilterExpression:{
... email: { $exists: true, $gt : { $type : 10 } } } })
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.users.createIndex({ "fname": 1, "lname": 1, "mobile":1 },
... { unique: true, partialFilterExpression:{
... mobile: { $exists: true, $gt : { $type : 10 } } } })
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
Here is the query :
>db.users.insert({fname:"tony",lname:"stark",mobile:"123",email:"123#gmail.com"})
WriteResult({ "nInserted" : 1 })
>db.users.insert({fname:"tony",lname:"stark",mobile:"123",email:"123#gmail.com"})
WriteResult({ "nInserted" : 1 })
Mongo version - v3.2.0
I have no experience with mongodb much neither have used indexes in other db's , i guess it's kind of noob question .Thanks in advance
I have an post whose field postStatus I want to set as either true false, or null. I was wondering whether mongo would be able to index null values.
Also, is there any difference if I choose to do null, true and false vs using -1,0,1 (or any 3 ints)?
thanks
Indexing of null
Yes, null values are indexed, as can be proven if you try to add a second null value to a unique index:
connecting to: test
> db.idxtest.createIndex({a:1},{unique:true})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.idxtest.insert({a:"foo"})
WriteResult({ "nInserted" : 1 })
> db.idxtest.insert({b:"bar"})
WriteResult({ "nInserted" : 1 })
> db.idxtest.insert({c:"baz"})
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 11000,
"errmsg" : "E11000 duplicate key error index: test.idxtest.$a_1 dup key: { : null }"
}
})
Another way to demonstrate that null values matter is by sorting on an indexed field for which documents contain null values:
> db.idxtest2.createIndex({a:1})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.idxtest2.insert({a:1})
WriteResult({ "nInserted" : 1 })
> db.idxtest.insert({a:2})
WriteResult({ "nInserted" : 1 })
> db.idxtest2.insert({b:2})
WriteResult({ "nInserted" : 1 })
> db.idxtest2.insert({a:null})
WriteResult({ "nInserted" : 1 })
> db.idxtest2.find().sort({a:1})
{ "_id" : ObjectId("56786a93ada44c7ffcd38f9f"), "b" : 2 }
{ "_id" : ObjectId("56786aa1ada44c7ffcd38fa0"), "a" : null }
{ "_id" : ObjectId("56786a65ada44c7ffcd38f9d"), "a" : 1 }
> db.idxtest2.find().sort({a:-1})
{ "_id" : ObjectId("56786a65ada44c7ffcd38f9d"), "a" : 1 }
{ "_id" : ObjectId("56786aa1ada44c7ffcd38fa0"), "a" : null }
{ "_id" : ObjectId("56786a93ada44c7ffcd38f9f"), "b" : 2 }
Note that implicit null values have precedence; so to say, they are "more" null since they do not even have the according key.
On Booleans
As per BSON specification, a boolean value is a single byte, whereas an integer is at least a 32-bit integer consuming 4 bytes. So it does make a difference and if you have millions of entries that would amount to... ...well, a few megabytes. ;) So for all practical purposes there is no difference.