mongodb replace all instances of certain value for subdocument - mongodb

My collection (called "workers"):
"_id" : "500"
"type" : "Manager",
"employees" : [{
"name" : "bob"
"id" : 101
},{
"name" : "phil"
"id" : 102
}]
Goal: for every _id that is a type: Manager AND that contains a subdocument that has an "id" of 102: replace 102 with 202.
Desired End result:
"_id" : "500"
"type" : "Manager",
"employees" : [{
"name" : "bob"
"id" : 101
},{
"name" : "phil"
"id" : 202
}]
I have tried:
db.workers.update({type:'Manager','employees.id':'102'},{$set:{'employees.id':'202'}},{multi:true})
I then did the following two things to verify:
db.workers.find({type: "Manager", 'employees.id': 102}).count()
I get a result of 9.
I also tried this to verify:
db.workers.find({$and: [{type: "Manager"},{"employees.id":60}]}).count()
This returned 0.
I am pretty confused at this point. Is my update wrong? is my find wrong? Is it both? Is the '9' result wrong? Is the '0' wrong?

You need to use the $ positional update operator to update the specific element that matched your query. Your update is also using values of '102' and '202' which makes the update try and match strings when those fields are numbers.
Your update should look like this instead:
db.workers.update(
{type: 'Manager', 'employees.id': 102},
{$set: {'employees.$.id': 202}},
{multi: true})

Related

Use distinct() on a variable in mongodb

I'm trying several queries in mongodb. Each document of my colelction is like this :
{
"_id" : 1,
"name" : 1,
"isReferenceProteome" : 1,
"isRepresentativeProteome" : 1,
"component" : 1,
"reference" : 1,
"upid" : 1,
"modified" : 1,
"taxonomy" : 1,
"superregnum" : 1,
"description" : 1,
"dbReference" : 1
}
the "reference" field has nested fields, one is "authorList", an array containing 'name' fields.
"reference" {
"authorList" [
{"name": "author1"},
{"name": "author2"},
{"name": "author3"} ...etc...
]
}
I have stored in a variable the result of the following query :
var testing = db.mycollection.find({'reference.authorList.30': {$exists: true}})
which stores all documents where the authorList is at least 30 names long.
Then I wanted to use distinct() on this variable, in order to have the distinct names of all authors :
testing.distinct("reference.authorList.name")
I tried this way because my first query returned an empty array :
db.mycollection.distinct( "reference.authorList.name", {"reference.authorList.name.30": {$exists: true}} )
I'm also trying whit $where command, but I got syntaxError for now.
What I am missing ?
Thanks.
Use
db.head_human_prot.distinct( "reference.authorList.name", {"reference.authorList.30": {$exists: true}} )
instead of
db.head_human_prot.distinct( "reference.authorList.name", {"reference.authorList.name.30": {$exists: true}} )
Silly me...

Mongo query with 'like' (regex); extract the field that provide the matching

I'm looking some way for extract the field that provide matching. Example from mongo shell:
db.estates.find({$or: [{street: /a/i}, {number: '64'}]}, {street: 1, number: 1})
{ "_id" : ObjectId("551f8b1efec981df83afbaee"), "number" : "123", "street" : "abcd" }
{ "_id" : ObjectId("551f8b36fec981df83afbb05"), "street" : "qwer", "number" : "64" }
I want to get in results some value pointing to field that provided the matching, or get only this field. Is it real?

MongoDB update a subdocument attribute

Let me start by saying I'm sorry if this has been answered, but I can't get other questions on this site to fit my needs and, more importantly, work.
I have the below example document, with a subdocument of 'address':
{
"_id" : ObjectId("....")
,"addresses" :
[{
"start" : ISODate("1973-07-10T00:11:51.111Z")
,"value" : "123 long road"
}]
}
What I need to do is to close the existing address record with an end attribute, and add a new line for the new address with a new start and value attribute. Eventually, I'll need to do this again so the code needs to update the subdocument record where end does not exist.
The below code does not work, but it's about as far as I can get:
db.sites.update(
{"_id" : ObjectId("....")
, "addresses.end" : {"$exists" : false}}
,{"$set": {"addresses.$.end" : "fdsa"}});
This gives the error:
Cannot apply the positional operator without a corresponding query field containing an array.
Can anyone point me in the right direction?
Juste replace in your query "addresses.end" : {"$exists" : false} with:
addresses: {$elemMatch: {end: {$exists: false}}}
Your address field is poorly defined. you need make it a subdocument or an array of subdocuments. ie {
"_id" : ObjectId("....")
,"addresses" :
[
{
"start" : ISODate("1973-07-10T00:11:51.111Z")
,"value" : "123 long road"
}
]
}
your query should then work!
I think that the Query should be more specific
**Updated **
db.sites.update ( {"_id" : ObjectId("...."), addresses: { "$elemMatch" : { end:{$exists : false}} } }, {"$set": {"addresses.$.end" : "fdsa"}});
db.sites.find()
results:
{
"_id" : ObjectId("53df93da560b7815e1237934"),
"addresses" : [
{
"start" : ISODate("1973-07-10T00:11:51.111Z"),
"value" : "123 long road",
"end" : "fdsa"
}
]
}
but you can update only one
Take a look http://docs.mongodb.org/manual/reference/operator/projection/positional/#proj.S
You can t update more element in Array https://jira.mongodb.org/browse/SERVER-1243

mongodb: remove subdocument with where clause that includes document & subdocument

Here is my collection (workers):
"type" : "Manager",
"employees" : [{
"name" : "bob"
"id" : 101
},{
"name" : "phil"
"id" : 102
},{
"name" : "bob"
"id" : 103
}]
First: this is NOT an array so $pullAll will not work or other array commands. All I want to do is: (1) search the collection for id 101 in ALL subdocuments with type Manager. (2) If 101 exists in a "Manager" subdocument, I want to remove item 103.
I have been pouring over the interwebs for two days on this issue and cannot figure it out.
I've tried this (and many other variations):
db.workers.update( {"type":"Manager","employees.id":101},{$pull : {"employees.id" : {"id" : 103}}},false,true)
The syntax of your $pull object is off. Try this instead:
db.workers.update({"type":"Manager","employees.id":101},
{$pull : {"employees" : {"id" : 103}}},false,true)
To confirm they were removed:
db.workers.find({
type: "Manager",
$and: [{'employees.id': 101}, {'employees.id': 103}]
})

MongoDB queries with null value

My collection (MongoDB v 2.0.2) has following records:
db.organization.find({})
{ "_id" : 1001, "path" : [ ], "parent" : null }
{ "_id" : 1002, "path" : [ 1001 ], "parent" : NumberLong(1001) }
organization has indexes:
db.organization.ensureIndex({"path":1});
db.organization.ensureIndex({"parent":1},{sparse:false});
(note I put awarnes sparse : false - to grant that null is indexed)
But, executing:
db.organization.find({"parent":null})
Returns empty set. What is wrong? Thank you in advance
I had the same issue. After reading the following documents
querying and nulls
BSON specification
I tried to query for the different BSON element types and found that my null was represented as a BSON element type 6 (undefined, deprecated) instead of the expected BSON element type 10 (null).
db.collection.find({ field: { "$type" : 6} };
Just checked following script at 2.0 and 2.0.2:
db.items.insert({ "_id" : 1001, "path" : [ ], "parent" : null })
db.items.insert({ "_id" : 1002, "path" : [ 1001 ], "parent" : NumberLong(1001) })
db.items.ensureIndex({"path":1});
db.items.ensureIndex({"parent":1},{sparse:false});
db.items.find({"parent":null})
actually returns one document that you expect:
{ "_id" : 1001,
"path" : [],
"parent" : null }
Also you can look into this doc about querying and nulls, probably should help you avoid possible future mistakes.