removing an object from a mongodb document - mongodb

I have a document in Mongodb collection, where I want to remove an object, using title key.
I tried using $unset, but it only removes the title key not the object to which it belongs.
{
"_id" : ObjectId("576b63d49d20504c1360f688"),
"books" : [
{
"art_id" : ObjectId("574e68e5ac9fbac82489b689"),
"title" :"abc",
"price" : 40
},
{
"art_id" : ObjectId("575f9badada0500d192c53f4"),
"title" : "xyz",
"price" : 20
},
{
"art_id" : ObjectId("57458224d86b3d1561150f17"),
"title" : "def",,
"price" : 30
}
],
"user_id" : "575570c315e27d13167dfc0d"
}

To remove the entire object that contains the query object use db.remove() query.
For your case:
db.yourcollection.remove({"books.title": "abc"});
Please double check the format in which the element of array is referenced.
This removes the entire objects that contains the embedded query obj. To remove only a single object, provide it with another field to uniquely identify it.
If you only want to remove the object that contains the title field from the array but wants to keep the object that contains the array, then please use the $pull operator. This answer will be of help.
Example: if you want to remove object
{
"art_id" : ObjectId("574e68e5ac9fbac82489b689"),
"title" :"abc",
"price" : 40
}
just from the array but keep the parent object like
{
"_id" : ObjectId("576b63d49d20504c1360f688"),
"books" : [
{
"art_id" : ObjectId("575f9badada0500d192c53f4"),
"title" : "xyz",
"price" : 20
},
{
"art_id" : ObjectId("57458224d86b3d1561150f17"),
"title" : "def",,
"price" : 30
}
],
"user_id" : "575570c315e27d13167dfc0d"
}
use
db.mycollection.update(
{'_id': ObjectId("576b63d49d20504c1360f688")},
{ $pull: { "books" : { "title": "abc" } } },
false,
true
);

$unset won't remove the object from an array. The $unset operator deletes a particular field. doc.
Use $pull instead.
The $pull operator removes from an existing array all instances of a value or values that match a specified condition.
Try following query
db.collName.update({$pull : {books:{title:abc}}})
Refer $pull-doc
Hope this will help you.

And if... ¿Do I want to delete an object that is inside a document and not as an array?
{
"_id" : ObjectId("576b63d49d20504c1360f688"),
"books" : {
"574e68e5ac9fbac82489b689": {
"art_id" : ObjectId("574e68e5ac9fbac82489b689"),
"title" :"abc",
"price" : 40
},
"575f9badada0500d192c53f4": {
"art_id" : ObjectId("575f9badada0500d192c53f4"),
"title" :"xyz",
"price" : 20
},
"57458224d86b3d1561150f17": {
"art_id" : ObjectId("57458224d86b3d1561150f17"),
"title" : "def",
"price" : 30
}
},
"user_id" : "575570c315e27d13167dfc0d"
}
The solutions is this:
db.auctions.update(
{'_id': ObjectId("576b63d49d20504c1360f688")},
{$unset: {"books.574e68e5ac9fbac82489b689":
{_id: "574e68e5ac9fbac82489b689"}}})

Try using pull.
https://docs.mongodb.com/manual/reference/operator/update/pull/
$pull
The $pull operator removes from an existing array all instances of a value or values that match a specified condition.
The $pull operator has the form:
{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
To specify a <field> in an embedded document or in an array, use dot notation.

Try in the mongo shell
db.yourcollection.remove({books:[{title:'title_you_want'}]})
Careful with the braces.

Related

How to PULL multiple value from a list in a document in mongoDB? [duplicate]

Hi I'm trying to remove multiple objects from an array that looks like this.
{
"_id" : ObjectId("5a7da1bda21d5f3e8cf005b3"),
"owner" : "1",
"group_name" : "PAASCU Board",
"group_members" : [
{
"faculty_name" : "Cheska Dela Rosa",
"faculty_number" : 2,
"_id" : ObjectId("5a7da1bda21d5f3e8cf005b5")
},
{
"faculty_name" : "Earl Sempio",
"faculty_number" : 7323,
"_id" : ObjectId("5a7da1bda21d5f3e8cf005b4")
},
{
"faculty_number" : 203,
"faculty_name" : "Sample",
"_id" : ObjectId("5a7dbf7952bd150a94d83958")
},
{
"faculty_number" : 8025,
"faculty_name" : "Sample Postman",
"_id" : ObjectId("5a7dc64a1cf5dd3d50167d53")
}
],
"__v" : 0 }
It works when I remove a single object using the $pull with this code.
db.getCollection('groups').update({_id: ObjectId("5a7da1bda21d5f3e8cf005b3")}, {$pull: {"group_members": {"faculty_number":8025}}})
But what if I want to remove multiple objects with different faculty_number? I tried using the $each method just like how I add multiple objects in the array but it doesn't work well.
Use $in operator to pass the list of faculty values to remove documents from embedded array. More here
Try
db.groups.update(
{"_id": ObjectId("5a7da1bda21d5f3e8cf005b3")},
{"$pull":{"group_members":{"faculty_number":{$in:[8025,7323]}}}}
)

Mongodb aggregate lookup return only one field of array

i have some collections for our project.
Casts collection contains movie casts
Contents collection contains movie contents
i want to run aggregate lookup for get information about movie casts with position type.
i removed collections details unnecessary fields.
Casts details:
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_name" : "",
"en_name" : "Ehsan",
"fa_bio" : "",
"en_bio" : ""
}
Contents details:
{
"_id" : ObjectId("5a6b8b734f1408137f79e2cc"),
"casts" : [
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_fictionName" : "",
"en_fictionName" : "Ehsan2",
"positionType" : {
"id" : 3,
"fa_name" : "",
"en_name" : "Director"
}
},
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_fictionName" : "",
"en_fictionName" : "Ehsan1",
"positionType" : {
"id" : 3,
"fa_name" : "",
"en_name" : "Writers"
}
}
],
"status" : 0,
"created" : Timestamp(1516997542, 4),
"updated" : Timestamp(1516997542, 5)
}
when i run aggregate lookup with bellow query, in new generated lookup array only one casts contents If in accordance with above casts array value aggregate lookup should return two casts content with two type. in casts array value exists two type of casts, 1) writers and directors. but returned director casts content. _casts should contains two object not one object!
aggregate lookup query:
{$lookup:{from:"casts",localField:"casts._id",foreignField:"_id",as:"_casts"}}
result:
{
"_id" : ObjectId("5a6b8b734f1408137f79e2cc"),
"casts" : [
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_fictionName" : "",
"en_fictionName" : "Ehsan2",
"positionType" : {
"id" : 3,
"fa_name" : "",
"en_name" : "Director"
}
},
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_fictionName" : "",
"en_fictionName" : "Ehsan1",
"positionType" : {
"id" : 3,
"fa_name" : "",
"en_name" : "Writers"
}
}
],
"_casts" : [
{
"_id" : ObjectId("5a6cf47415621604942386cd"),
"fa_name" : "",
"en_name" : "Ehsan",
"fa_bio" : "",
"en_bio" : ""
}
],
"status" : 0,
"created" : Timestamp(1516997542, 4),
"updated" : Timestamp(1516997542, 5)
}
EDIT-1
finally my problem is solved. i have only one problem with this query, this query doesn't show root document fields. finally solve this problem. finally query exists in EDIT-2.
query:
db.contents.aggregate([
{"$unwind":"$casts"},
{"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"casts.info"}},
{"$unwind":"$casts.info"},
{"$group":{"_id":"$_id", "casts":{"$push":"$casts"}}},
])
EDIT-2
db.contents.aggregate([
{"$unwind":"$casts"},
{"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"casts.info"}},
{"$unwind":"$casts.info"},
{$group:{"_id":"$_id", "data":{"$first":"$$ROOT"}, "casts":{"$push":"$casts"}}},
{$replaceRoot:{"newRoot":{"$mergeObjects":["$data",{"casts‌​":"$casts"}]}}},
{$project:{"casts":0}}
]).pretty()
This is expected behavior.
From the docs,
If your localField is an array, you may want to add an $unwind stage
to your pipeline. Otherwise, the equality condition between the
localField and foreignField is foreignField: { $in: [
localField.elem1, localField.elem2, ... ] }.
So to join each local field array element with foreign field element you have to $unwind the local array.
db.content.aggregate([
{"$unwind":"$casts"},
{"$lookup":{"from":"casts","localField":"casts._id","foreignField":"_id","as":"_casts"}}
])
Vendor Collection
Items Collection
db.items.aggregate([
{ $match:
{"item_id":{$eq:"I001"}}
},
{
$lookup:{
from:"vendor",
localField:"vendor_id",
foreignField:"vendor_id",
as:"vendor_details"
}
},
{
$unwind:"$vendor_details"
},
{
$project:{
"_id":0,
"vendor_id":0,
"vendor_details.vendor_company_description":0,
"vendor_details._id":0,
"vendor_details.country":0,
"vendor_details.city":0,
"vendor_details.website":0
}
}
]);
Output
Your Casts collection shows only 1 document. Your Contents collection, likewise, shows only 1 document.
This is 1 to 1 - not 1 to 2. Aggregate is working as designed.
The Contents document has 2 "casts." These 2 casts are sub-documents. Work with those as sub-documents, or re-design your collections. I don't like using sub-documents unless I know I will not need to use them as look-ups or join on them.
I would suggest you re-design your collection.
Your Contents collection (it makes me think of "Movies") could look like this:
_id
title
releaseDate
genre
etc.
You can create a MovieCasts collection like this:
_id
movieId (this is _id from Contents collection, above)
castId (this is _id from Casts collection, below)
Casts
_id
name
age
etc.

Get specific object in array of array in MongoDB

I need get a specific object in array of array in MongoDB.
I need get only the task object = [_id = ObjectId("543429a2cb38b1d83c3ff2c2")].
My document (projects):
{
"_id" : ObjectId("543428c2cb38b1d83c3ff2bd"),
"name" : "new project",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b"),
"members" : [
ObjectId("5424ac37eb0ea85d4c921f8b")
],
"US" : [
{
"_id" : ObjectId("5434297fcb38b1d83c3ff2c0"),
"name" : "Test Story",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b"),
"tasks" : [
{
"_id" : ObjectId("54342987cb38b1d83c3ff2c1"),
"name" : "teste3",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
},
{
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
]
}
]
}
Result expected:
{
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
But i not getting it.
I still testing with no success:
db.projects.find({
"US.tasks._id" : ObjectId("543429a2cb38b1d83c3ff2c2")
}, { "US.tasks.$" : 1 })
I tryed with $elemMatch too, but return nothing.
db.projects.find({
"US" : {
"tasks" : {
$elemMatch : {
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2")
}
}
}
})
Can i get ONLY my result expected using find()? If not, what and how use?
Thanks!
You will need an aggregation for that:
db.projects.aggregate([{$unwind:"$US"},
{$unwind:"$US.tasks"},
{$match:{"US.tasks._id":ObjectId("543429a2cb38b1d83c3ff2c2")}},
{$project:{_id:0,"task":"$US.tasks"}}])
should return
{ task : {
"_id" : ObjectId("543429a2cb38b1d83c3ff2c2"),
"name" : "jklasdfa_XXX",
"author" : ObjectId("5424ac37eb0ea85d4c921f8b")
}
Explanation:
$unwind creates a new (virtual) document for each array element
$match is the query part of your find
$project is similar as to project part in find i.e. it specifies the fields you want to get in the results
You might want to add a second $match before the $unwind if you know the document you are searching (look at performance metrics).
Edit: added a second $unwind since US is an array.
Don't know what you are doing (so realy can't tell and just sugesting) but you might want to examine if your schema (and mongodb) is ideal for your task because the document looks just like denormalized relational data probably a relational database would be better for you.

MongoDB Query double nested documents in array

I was wondering how I can query from an embedded document inside an array. I have following structure:
{ "targetId" : 2, "metaData" : [ { "key" : "id", "value" : 1 }, { "key" : "name", "value" : "Parisa" }, { "key" : "img", "value" : { "imgid" : 1, "imgName" : "img1" } } ]
I could search simple key-values like key = id and value =1, but I could not search based on the values with embedded document e.g. key="img"
I tried following query but it does not work:
db.test.find({"metaData":{$elemMatch:{"key":"img", "value":{"imgid":1}}}})
Could you please help me!
I think the "value" part of your query is a little off. You need to put the document element in the criteria:
b.test.find({"metaData":{$elemMatch:{"key":"img", "value.imgid":1}}})

How to update particular array element in MongoDB

I am newbie in MongoDB. I have stored data inside mongoDB in below format
"_id" : ObjectId("51d5725c7be2c20819ac8a22"),
"chrom" : "chr22",
"pos" : 17060409,
"information" : [
{
"name" : "Category",
"value" : "3"
},
{
"name" : "INDEL",
"value" : "INDEL"
},
{
"name" : "DP",
"value" : "31"
},
{
"name" : "FORMAT",
"value" : "GT:PL:GQ"
},
{
"name" : "PV4",
"value" : "1,0.21,0.00096,1"
}
],
"sampleID" : "Job1373964150558382243283"
I want to update the value to 11 which has the name as Category.
I have tried below query:
db.VariantEntries.update({$and:[ { "pos" : 117199533} , { "sampleID" : "Job1373964150558382243283"},{"information.name":"Category"}]},{$set:{'information.value':'11'}})
but Mongo replies
can't append to array using string field name [value]
How one can form a query which will update the particular value?
You can use the $ positional operator to identify the first array element to match the query in the update like this:
db.VariantEntries.update({
"pos": 17060409,
"sampleID": "Job1373964150558382243283",
"information.name":"Category"
},{
$set:{'information.$.value':'11'}
})
In MongoDB you can't adress array values this way. So you should change your schema design to:
"information" : {
'category' : 3,
'INDEL' : INDEL
...
}
Then you can adress the single fields in your query:
db.VariantEntries.update(
{
{"pos" : 117199533} ,
{"sampleID" : "Job1373964150558382243283"},
{"information.category":3}
},
{
$set:{'information.category':'11'}
}
)