I have a mongo Document structure like this with comments field as embedded doc.
i want to add "newField" : "something" to embedded comments field with "cid" : "17426944" :
in java driver i tried :
BasicDBObject query = new BasicDBObject(); // MongoDB query
BasicDBObject record = new BasicDBObject(); // MongoDB record
BasicDBObject dbObject = new BasicDBObject(); // fieldsToUpdate
query.put("comments.cid","17426944");
dbObject.put("comments.newField","something");
record.put("$set",dbObject );
mongoCtrl.updateCollection(query, record, false, true); // mongoCtrl is my connection contrl
problem here is :
com.mongodb.MongoException: cannot use the part (comments of comments.newField) to traverse the element ({comments:[ .......... ]})
at com.mongodb.CommandResult.getException(CommandResult.java:100)
at com.mongodb.CommandResult.throwOnError(CommandResult.java:134)
at com.mongodb.DBTCPConnector._checkWriteError(DBTCPConnector.java:142)
sample doc :
{
"_id" : ObjectId("53abb8d17bfd6b92e2398d34"),
"name" : "satish",
"number": "1122112",
"comments" : [
{
"cid" : "17426944"
},
{
"cid" : "607395840"
},
{
"cid" : "393084416"
}
]
}
what i need :
{
"_id" : ObjectId("53abb8d17bfd6b92e2398d34"),
"name" : "satish",
"number": "1122112",
"comments" : [
{
"cid" : "17426944",
"newField" : "something"
},
{
"cid" : "607395840"
},
{
"cid" : "393084416"
}
]
}
Plz help me.Thanks vijay
Pretty close, you just missed the positional $ operator to match the position of the array found in your query portion:
BasicDBObject query = new BasicDBObject(); // MongoDB query
BasicDBObject record = new BasicDBObject(); // MongoDB record
BasicDBObject dbObject = new BasicDBObject(); // fieldsToUpdate
query.put("comments.cid","17426944");
dbObject.put("comments.$.newField","something");
record.put("$set",dbObject );
mongoCtrl.updateCollection(query, record, false, true);
Related
I have the following collections in MongoDB
"userDetails" : [
{
"user" : DBRef("users", "RAVI"),
"class1" : DBRef("classes", "1"),
"class2" : DBRef("classes", "2")
},
{
"user" : DBRef("users", "TEJA"),
"class1" : DBRef("classes", "1"),
"class2" : DBRef("classes", "2")
}]
classes
{
"_id" : "1",
"maxScore" : "50",
"subject" : DBRef("subjects", "class1")
}
{
"_id" : "2",
"maxScore" : "80",
"subject" : DBRef("subjects", "class2")
}
users{
"_id" : "RAVI",
"address" : "3-2-2222",
"lastClass" : "1"
"lastScore" : ""
}
{
"_id" : "TEJA",
"address" : "5-23",
"lastClass" : "1"
}
From java program, I want to query such that when I pass input as user name I want to fetch all the details of that user and his classes details.can anyone help me out with this?
previously i tried
BasicDBObject fields = new BasicDBObject("userDetails", 1).append("userDetails", new BasicDBObject("$elemMatch", new BasicDBObject("user.$id", "RAVI")));
BasicQuery query = new BasicQuery(new BasicDBObject(), fields);
List<UserDetails> usrDetailsList = mongoTemplate.find(query, UserDetails.class);
//Considering you have data inserted in your collection, now this following code will fetch a specific record from collection:
BasicDBObject whereQuery = new BasicDBObject();
whereQuery.put("user","RAVI"); //here you are specifying that you want all details of user-RAVI
DBCursor cursor = collection.find(whereQuery);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
I got my solution with a minor change.I removed $ symbol before id and i got my answer
BasicDBObject fields = new BasicDBObject("userDetails", 1).append("userDetails", new BasicDBObject("$elemMatch", new BasicDBObject("user.id", "RAVI")));
BasicQuery query = new BasicQuery(new BasicDBObject(), fields);
List<UserDetails> usrDetailsList = mongoTemplate.find(query, UserDetails.class);
but i got stuck in another point.I want to search my query based on subject id something like following
BasicDBObject fields = new BasicDBObject("userDetails", 1).append("userDetails", new BasicDBObject("$elemMatch", new BasicDBObject("class1.$subject.$id", "class1")));
BasicQuery query = new BasicQuery(new BasicDBObject(), fields);
List<UserDetails> usrDetailsList = mongoTemplate.find(query, UserDetails.class);
I have a documents in mongo db as follows. I want to get and update the document having policyMap equals CostCalculation.In this CostCalculation has array format update in array elements such as 'policyName' have 'CostCalculationPolicyuserDefine' and set 'policyDes' = 'New Value' Please suggest the java code to solve this.
I searched mongo operartors but couldn't get it.
Sample mongo db document structure.
{
"policyMap" : {
"CostCalculation" : [{
"policyName" : "CostCalculationPolicyuserDefine",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
},
{
"policyName" : "CostCalculationPolicyuserDefine1",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
}]
},
"bsVer" : 2,
"bsFlag" : true,
"crBy" : "xxxxx",
"crDate" : NumberLong("1440138385345"),
"entNm" : "xxxx"
}
{
"policyMap" : {
"CostValue" : [{
"policyName" : "CostValuePolicyuserDefine",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
},
{
"policyName" : "CostCalculationPolicyuserDefine1",
"policyDesc" : "Priority user Defined Policy",
"userDefined" : 1
}]
},
"bsVer" : 2,
"bsFlag" : true,
"crBy" : "xxxxx",
"crDate" : NumberLong("1440138385345"),
"entNm" : "xxxx"
}
My sample java code
DBCollection coll = db.getCollection("nestedtest");
BasicDBObject searchDocument = new BasicDBObject();
searchDocument.put( "policyMap ", new BasicDBObject("$exists", new BasicDBObject("$eq", "CostCalculation")));
coll.remove(searchDocument);
What would be the similar java code to get the correct result.
Thanks.
This code works using Mongo 3 java drivers. It removes the need for all the BasicDBObjects that are in your code:
MongoClientURI uri = new MongoClientURI("mongodb://localhost:27017");
MongoClient client = new MongoClient(uri);
initialiseCollection(client);
Bson filter = Filters.exists("policyMap.costCalculation");
client.getDatabase("test").getCollection("test").deleteOne(filter);
DBCollection coll = db.getCollection("minnalPolicyMetadata");
BasicDBObject searchDocument = new BasicDBObject();
searchDocument.put("policyMap.CostCalculation",new BasicDBObject("$exists",true));
DBCursor cursor = coll.find(searchDocument);
if(cursor.count() != 0){
while(cursor.hasNext())
System.out.println(cursor.next());
}
In this way i solved this problem.Use exists operator in mongo
I am trying to update a filed 'Content' of a document in sharded environment. My shard key is 'asset' which is included in the query. But I am getting error saying
"com.mongodb.WriteConcernException: { "serverUsed" :
"/10.102.10.190:27017" , "err" : "update { q: { $and: [ { asset:
\"/1/01/01.m3u8\" }, { recList: \"REC-1-1418208180000-1418208300000\"
} ] }, u: { $set: { Content: BinData } }, multi: false, upsert: false
} does not contain _id or shard key for pattern { asset: 1 }" , "code"
: 61 , "n" : 0 , "shards" : [ ] , "shardRawGLE" : { } , "ok" : 1.0} "
BasicDBObject newDocument = new BasicDBObject();
newDocument.append("$set", new BasicDBObject().append("Content", content));
BasicDBObject andQuery = new BasicDBObject();
List<BasicDBObject> obj = new ArrayList<BasicDBObject>();
obj.add(new BasicDBObject("asset", assetf));
obj.add(new BasicDBObject("recList", recId));
andQuery.put("$and", obj);
WriteResult result = collection.update(andQuery, newDocument);
Please help me.
I am new to mongodb. Plz help me with this.
I need a document like this
employee{
_id:111,
name:xxx,
dependents : [ {
name:a,
age:51,
dep_children:[{name:aa}{name:bb}{name:c}]
}
{
name:b,
age:52,
dep_children:[{name:aa}{name:bb}{name:c}]
}
{
name:c,
age:51,
dep_children:[{name:aa}{name:bb}{name:cc}]
}
]
}
I am using the below script to migrate data for SQL and update it into mongoDB
My code looks something like this:
while(personcount>=0)
{
BasicDBObject doc = new BasicDBObject("_id",ind1.get(count)).
append("name",ind2.get(count));
coll.insert(doc);
while(dependentcount>0)
{
BasicDBObject querymongo = new BasicDBObject();
querymongo.put( "name",ind.get(count));
BasicDBObject tenant = new BasicDBObject();
tenant.put("name",indsa.get(innercount) );
tenant.put("age", indsa2.get(innercount));
BasicDBObject update = new BasicDBObject();
update.put("$push", new BasicDBObject("dependents",tenant));
coll.update(querymongo, update,true,true);
while(kidcount>0)
{
BasicDBObject querymongofact = new BasicDBObject();
querymongokid.put( "dependent.name",indsa.get(innercount));
BasicDBObject tenantkid = new BasicDBObject();
tenantkid .put("name",indfact.get(innercountfact) );
BasicDBObject updatekid = new BasicDBObject();
updatekid .put("$push", new BasicDBObject("dependent.dep_children",tenantkid));
coll.update(querymongokid, updatekid ,true,true);
}
}
}
when we print querymongokid and updatekid, the data inside it are expected values itself. This code is not throwing any error. But in data base the only dep_children data is not getting updated . I am not getting wt went wrong. please help me
Thanks in advance
Your last query fails in the mongo driver in a sense that the update has no effect - but it's not an actual error. Just let me reproduce what you are doing in the mongo shell:
> db.coll.insert({_id:1,name:"name1"})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"a", age:50}}})
> db.coll.update({name:"name1"}, {"$push": {dependents: {name:"b", age:55}}})
> db.coll.findOne()
{
"_id" : 1,
"dependents" : [
{
"name" : "a",
"age" : 50
},
{
"name" : "b",
"age" : 55
}
],
"name" : "name1"
}
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.dep_children": {name:"aa"}}})
can't append to array using string field name: dep_children
> db.coll.update({"dependents.name": "a"}, {"$push": {"dependents.$.dep_children": {name:"aa"}}})
> db.coll.findOne()
{
"_id" : 1,
"dependents" : [
{
"age" : 50,
"dep_children" : [
{
"name" : "aa"
}
],
"name" : "a"
},
{
"name" : "b",
"age" : 55
}
],
"name" : "name1"
}
Unfortunately, I have very little experience with the native mongo java driver (I'm usually on Spring data), but changing your line
updatekid.put("$push", new BasicDBObject("dependent.dep_children",tenantkid));
to
updatekid.put("$push", new BasicDBObject("dependent.$.dep_children",tenantkid));
should do the trick as well.
The reason for that behavior is that "dependent.dep_children" is not a valid selector as it corresponds to "go to field dep_children within the subdocument dependent". However, "dependent" happens to be an array without any fields. The $ replaces an explicit index and will make sure the correct subdocument from your query is selected.
Also see here for a less error-prone formulation of your query - without using $elemMatch it will only work if your query uniquely identifies a certain array element. With $elemMatch it will always work, but only update the first match.
I have a big problem with the api java mongodb. I use a request with the update methods of DBCollection class and in the mongodb i get a multiple same document while the value doesn't change,help me please. I don't want to have a duplicate document.
BasicDBObject query = new BasicDBObject();
query.append("ad", "man2ist").append("list.id", new BasicDBObject("$ne", "5")); // "list.id" : {$ne : 0 }
BasicDBObject a = new BasicDBObject("id",String.valueOf(5)).append("value", 100);
BasicDBObject upd = new BasicDBObject("$addToSet",new BasicDBObject("list",a));
System.out.println(query);
System.out.println(upd);
WriteResult r = dbc.update(query,upd,true,false);
//db.friends.update({ "ad" : "man2ist" , "list.id" : { $ne : "4"} },{ $addToSet : { "list" : { "id" : "4","value" : 100}}},true,true);
my document here :
{
"ad" : "man2ist",
"createdDate" : ISODate(),
"list" : [
{
"id" : "45",
"value" : 489
},
{
"id" : "5",
"value" : 20,
},
{
"id" : "4578",
"value" : 21,
} ]}
The problem is that you set the upset flag to true, meaning that the document should be created if no document matching the criteria is found. If there is no document matching the criteria in the db, the mongo shell will do the same.
If you change your query to this,
WriteResult r = dbc.update(query,upd,false,false);
it should work all the time.