MongoDB JSON array within JSON object field removal - java

I have a json object as following:
{ "_id" : ObjectId("508806803bb97dc546e6f307"), "user_name" : "user1", "user_id" : 45645645, "likes" : [ { "event_id" : NumberLong("4578541212") },{ "event_id" : NumberLong("4578541213") } ], "dislikes" : [ ] }
I'm trying to delete specific event within likes array via java drivers
tried doing this first in shell:
> db.users.update( {'likes.event_id' : 4578541212}, { '$unset':{'likes.event_id'
:1}})
with no luck...how can I manage doing that?

If you want to just remove the event_id field from the array element:
db.users.update( {'likes.event_id' : 4578541212}, {'$unset':{'likes.$.event_id' :1}})
Use the $pull operator to delete the element:
db.users.update({'likes.event_id': 4578541212}, {'$pull':{likes: {event_id: 4578541212}}})

Related

Trim the redundant data

I want to delete the data on the date basis(which is present inside the array). This is how my mongo document looks like.
{
"_id" : ObjectId("5d3d94df83f68f8bf751f367"),
"branchName" : "krishYogaCenter",
"Places" : [
"Pune",
"Bangalore",
"Hyderabad",
"Delhi"
],
"rulesForDateRanges" : [
{
"fromDate" : ISODate("2019-01-07T18:30:00.000Z"),
"toDate" : ISODate("2019-03-06T18:30:00.000Z"),
"place" : "Delhi",
"ruleIds" : [
5,
6,
7
]
},
{
"fromDate" : ISODate("2019-03-07T18:30:00.000Z"),
"toDate" : ISODate("2019-05-06T18:30:00.000Z"),
"place" : "Hyderabad",
"ruleIds" : [
1,
2
]
}
],
"updatedAt" : ISODate("2019-07-28T12:31:35.694Z"),
"updatedBy" : "Theia"
}
Here, if "toDate" is less than today I want to delete that object from the array "rulesForDateRanges". Searched on the google but did not get any way to do this in morphia.
If this date was not present internally in the array object then I could have used "delete document where the date is less than today". Here I want to remove that object from the array which is in no longer use, and if the array "rulesForDateRanges" becomes empty in that case only want to delete the whole document.
I am using morphia. Please suggest the way to do this in morphia or the query to do this.
Searched on google got this: We can get the document one by one from the collection using query and do UpdateOperation over that document. But here I have to perform updateOperation for each and every document.

Fetch Inner Json of Array using Mongo Cursor

Using Cursor need to fetch values of Inner Json which is in Array
Document looks like this
{
"_id" : ObjectId("5772932ce4b0be6213704c81"),
"employerId" : "57728cd7e4b0be6213704b17",
"jobSeekerId" : "5706426ae4b0c7ea74fda18b",
"readByJobSeeker" : true,
"readByJobEmployer" : true,
"interestChat" : [
{
"userChat" : "is this job avaliable ",
"lastChatRole" : "JOBSEEKER",
"lastChatTime" : ISODate("2017-08-10T15:20:25.017Z"),
"jobSeekerAcknowledgeFlag" : true,
"connectionCounterIncreamented" : false
}
],
"createdDate" : ISODate("2016-06-28T15:09:32.564Z"),
"lastModifiedDate" : ISODate("2017-08-10T15:31:12.564Z"),
"version" : NumberLong(20),
"active" : true
}
Issue is using query
db.interest.find({"interestChat":{$exists:true}}).forEach(function(myChat){print ("interest :: "+ myChat.interestChat); } ).pretty()
Not able to fetch data from Array as output come out as
interest :: [object BSON]
Need to fetch values of Inner json
The function print is not meant to bring json/bson objects.
Try printjson instead.
db.interest.find({"interestChat":{$exists:true}})
.forEach(function(myChat){
printjson({"interest": myChat.interestChat});
})
OR just printjson(myChat.interestChat);

MongoDB update element of nested array

I have a mongo collection named firma which has one of the document structure as below:
{
"_id" : ObjectId("5729af099b3ebf1d0ca7ff05"),
"musteriler" : [
{
"_id" : "de0bf813-b707-4a8d-afc2-9752e05c3aa5",
"yetkiliListesi" : [
{
"_id" : "a5e487fa-2034-4817-94f2-3bd837b76284",
"ad" : "Burak",
"soyad" : "Duman 1",
"cepTel" : "3333333333333",
"mail" : "asdf#asdf.com"
},
{
"_class" : "com.bisoft.entity.MusteriYetkili",
"_id" : "bc4b537d-522a-4c9a-9f67-8ca243e18f46",
"ad" : "Ridvan",
"soyad" : "ENİŞ",
"cepTel" : "222222222222",
"mail" : "asdf#asdf.com"
}
]
}
],
"defaultTimezone" : "Europe/Istanbul"
}
In the above json, I need to update element of second array(yetkiliListesi) which _id = "a5e487fa-2034-4817-94f2-3bd837b76284"
Since I am using a java application(using mongo java driver and spring boot MongoTemplate) to access it and execute this query :
mongoTemplate.updateFirst(Query.query(Criteria.where("_id").is("5729af099b3ebf1d0ca7ff05").and("musteriler.yetkiliListesi._id").is("a5e487fa-2034-4817-94f2-3bd837b76284")),
new Update().set("musteriler.yetkiliListesi.$", yetkiliDBO), Firma.class);
In the above query, yetkiliDBO is a BasicDBObject and its content :
yetkiliDBO = {
'_class': 'com.bisoft.entity.MusteriYetkili',
'_id': "a5e487fa-2034-4817-94f2-3bd837b76284",
'ad': 'wer',
'soyad': 'xyz',
'cepTel': "222222222222",
mail: "asdf#asdf.com"
}
when execute my query I have an error
com.mongodb.WriteConcernException: { "serverUsed" : "192.168.2.250:27017" , "ok" : 1 , "n" : 0 , "updatedExisting" : false , "err" : "cannot use the part (musteriler of musteriler.yetkiliListesi.0) to traverse the element
What I need to do?
You can not use the '$' placeholder when traversing nested arrays.
The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value
source
I would suggest restructuring your data into separate, less-nested collections.

retrieve values from nested json array in mongodb

My mongo collection has entries in the following format
{
"myobj" : {
"objList" : [
{ "location" : "Texas" },
{ "location" : "Houston"},
{ "name":"Sam" }
]
},
"category" : "cat1"
}
{
"myobj" :
{
"objList" : [
{ "location" : "Tennesy" },
{ "location" : "NY"},
{ "location" : "SF" }
]
},
"category" : "cat2"
}
I want to extract the "**category**" where location is "Houston". In case of simple JSON object I have to just pass it as query like:
BasicDBObject place = new BasicDBObject();
place.put("location", "Houston");
But in case of nested JSON I don't know how to pass it as a query and get the appropriate category. ie If I pass my location as"Houston" then it should return it's appropriate category "cat1"...i hope my question is clear now....
Ok, you have your documents:
db.coll1.insert({
"myobj" : {
"objList" : [
{ "location" : "Texas" },
{ "location" : "Houston"},
{ "name":"Sam" }
]
},
"category" : "cat1"
})
and
db.coll1.insert({
"myobj" : {
"objList" : [
{ "location" : "Tennesy" },
{ "location" : "Houston"},
{ "location" : "SF" }
]
},
"category" : "cat1"
})
Now you can find what you want using the dot operator:
db.coll1.find({"myobj.objList.location": "Texas"}).pretty() will return one object which has Texas
db.coll1.find({"myobj.objList.location": "SF"}).pretty() will return one object which has SF
db.coll1.find({"myobj.objList.location": "Houston"}).pretty() will return both objects
And now I hope you will be able to write it in Java. I have never used Java, but based on this question you can do something like this. If it will not work, just look how to use dot operator in java driver for mongo:
DBCursor cursor = coll1.find(new BasicDBObject("myobj.objList.location", "Texas"));
P.S. you told, that you wanted to retrieve category. In such a way, you will need to use a projection db.coll1.find({<the query I provided}, {category: 1, _id: 0})

How to construct query to update nested array document in mongo?

I am having following document in mongo,
{
"_id" : ObjectId("506e9e54a4e8f51423679428"),
"description" : "ffffffffffffffff",
"menus" : [
{
"_id" : ObjectId("506e9e5aa4e8f51423679429"),
"description" : "ffffffffffffffffffff",
"items" : [
{
"name" : "xcvxc",
"description" : "vxvxcvxc",
"text" : "vxcvxcvx",
"menuKey" : "0",
"onSelect" : "1",
"_id" : ObjectId("506e9f07a4e8f5142367942f")
} ,
{
"name" : "abcd",
"description" : "qqq",
"text" : "qqq",
"menuKey" : "0",
"onSelect" : "3",
"_id" : ObjectId("507e9f07a4e8f5142367942f")
}
]
},
{
"_id" : ObjectId("506e9e5aa4e8f51423679429"),
"description" : "rrrrr",
"items" : [ {
"name" : "xcc",
"description" : "vx",
"text" : "vxc",
"menuKey" : "0",
"onSelect" : "2",
"_id" : ObjectId("506e9f07a4e8f5142367942f")
} ]
}
]
}
Now , i want to update the following document :
{
"name" : "abcd",
"description" : "qqq",
"text" : "qqq",
"menuKey" : "0",
"onSelect" : "3",
"_id" : ObjectId("507e9f07a4e8f5142367942f")
}
I am having main documnet id: "_id" : ObjectId("506e9e54a4e8f51423679428") and menus id
"_id" : ObjectId("506e9e54a4e8f51423679428") as well as items id "_id" : ObjectId("507e9f07a4e8f5142367942f") which is to be updated.
I have tried using the following query:
db.collection.update({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} , "menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}},{ "$set" : { "menus.$.items" : { "_id" : { "$oid" : "506e9f07a4e8f5142367942f"}} , "menus.$.items.$.name" : "xcvxc66666", ...}},false,false);
but its not working...
The positional operator does not work on the number of levels you are trying to get it to work on ( https://jira.mongodb.org/browse/SERVER-831?focusedCommentId=22438&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel ) with menus.$.items.$.name and even if it did MongoDB query parser would have no idea what the other $ is from the find of the update.
You will need to pull out the items from the schema, update that seprately and then update the root document.
One good way of judging when queries should be done separately is to think that each menu sounds like a separate entity (or table in a relational database) as such you should probably work on updating those entites (or tables in a relational model) separately to the parent entity (table).
So first you would get out the main root document. Scroll across it's menus in client side and then $set that particular menu to the entire item you build on client side.
Edit
The way I imagine this work client side is (in pseudo code since my Java is a little rusty) by first getting that document in an active record fashion:
doc = db.col.find({ "_id" : { "$oid" : "506e9e54a4e8f51423679428"} ,
"menus._id" : { "$oid" : "506e9e5aa4e8f51423679429"}});
Then you would iterate through the document assigning your values:
foreach(doc.menus as menu_key => menu){
foreach(menu['items'] as key => item){
if(item._id == { "$oid" : "506e9f07a4e8f5142367942f"}){
doc.menus[menu_key][key][name] = "xcvxc66666"
}
}
}
And then simple save the doc after all changes are commited:
db.col.save(doc);
This is of course just one way of doing it and this way uses the activen record paradigm which I personally like. In this idea you would combine the find with everything else you need to modify on the document, building it up client side and then sending it all down as one single query to your DB.

Categories