I have below document structure in mongodb database:
{
"_id" : ObjectId("52ec7b43e4b048cd48499b35"),
"eidlist" : [
{
"eid" : "64286",
"dst" : NumberLong(21044),
"score" : 0
},
{
"eid" : "65077",
"dst" : NumberLong(21044),
"score" : 0
}
],
"src" : NumberLong(21047)
}
I would like to update score field of first object using Java-mongodb driver:
I tried following code but it is not working :( :
DBObject update_query=new BasicDBObject("src", key).append("eidlist.eid", e.getEdgeid());
DBObject data=new BasicDBObject("$set",new BasicDBObject("eidlist.score",100));
coll.update(update_query, data);
Please help me to solve this problem..I have checked all the parameter which I have passed to update function.I think something wrong with the update logic :(
You were close. You omiited the positional operator from the update. Edit your code as shown.
DBObject data=new BasicDBObject("$set",new BasicDBObject("eidlist.$.score",100));
Solution for this problem is:
DBObject data=new BasicDBObject("$set",new BasicDBObject("eidlist.$.score",""+100));
Ensure data type of every field used in the update query.It should be compatible with what we have stored in the mongodb :)
Related
Due to some decisions I will have to change the name of some fields in all documents in a single collection. For purpose of automation testing I am inserting documents and then checking some logics.
Lets assume that after the insert method I have the following objects:
"_id" : ObjectId("60c10042d"),
"Name" : Mike,
"years" : 25,
"Country" : England
},
{
"_id" : ObjectId("40r10042t"),
"Name" : Smith,
"years" : 32,
"Country" : England
}
When inserting the document/documents I want to change the field "Country" to "Occupation" using Java. Here is example of the code I'm using:
MongoCollection<Document> documentMongo = MongoDb.getCollection("collectionName");
Document document = Document.parse(readJsonFile(json));
//I've tried this way:
//documentMongo.updateMany(document, Updates.rename("Country", "Occupation"));
//didn't work
documentMongo.insertOne(document);
Oh, the rename should be after the insert is done.
documentMongo.insertOne(document);
documentMongo.updateMany(document, Updates.rename("Country", "Occupation"));
Anyway, it could help others which are searching for easy way to change field names.
Sadly, when I try rename more fields it works only for the first one.
Final solution:
documentMongoCollection.insertOne(document);
BasicDBObject searchQuery = new BasicDBObject();
BasicDBObject updateQuery = new BasicDBObject();
updateQuery.append("$rename",new BasicDBObject().append("oldField", "newField").append("oldField1", "newField1").append("oldField2", "newField2"));
documentMongoCollection.updateMany(searchQuery,updateQuery);
Two documents can have same IMAGE_CONTENT_INSTANCE_HANDLE and state can be BOOKED or RELEASED
but I want all image instances handles which are only RELEASED state,
Currently I am doing this by firing two queries it introduced performance issues.
{
"state" : "RELEASED"
}
with projection { "imageContentInstance.handle" : 1}
i am iterating through the result which is coming out from this query
and firing another query as below and excluding the handles which are also in BOOKED state from adding to the list.So i gets handles only in the RELEASED state
while (cursor.hasNext()) {
ICI ici = objectMapper.readValue(result, ICI_COLLECTION_TYPE_REF);
String result = JSON.serialize(cursor.next());
try {
queryDocument = { "imageContentInstance.handle" : ici.getImageContentInstance().getHandle() , "state" : "BOOKED"}
Document bookedDoc = iciDAO.findOne(queryDocument);
if (null != bookedDoc)
LOGGER.debug("Calling continue and skipping booked state ");
continue;
}
iciHandles.add(ici.getImageContentInstance().getHandle().toString());
LOGGER.debug("ImageInstanceHandle is added to the lisr and the lise is "+iciHandles.size());
}
I want to achieve this in a single mongo query as an example query written in sql to increase performance .I really appreciate your comments .
SELECT *
FROM ici i
WHERE i.state = 'RELEASED'
AND NOT EXISTS
(SELECT * FROM ici ic WHERE ic.handle = i.handle AND ic.state = 'BOOKED'
);
example :
Suppose the documents are as below
{
"_id" : ObjectId("58c9f524fa8cd6a517cf5ddf"),
"imageContentInstance" : {
"handle" : "ICI:1234",
"key" : null,
}
"instanceHandle" : "LCI:RNBM12",
"state" : "BOOKED",
}
{
"_id" : ObjectId("58c9f524fa8cd6a517cf5ddf"),
"imageContentInstance" : {
"handle" : "ICI:1234",
"key" : null,
}
"instanceHandle" : "LCI:RNBM13",
"state" : "RELEASED",
}
{
"_id" : ObjectId("58c9f524fa8cd6a517cf5ddf"),
"imageContentInstance" : {
"handle" : "ICI:456",
"key" : null,
}
"instanceHandle" : "LCI:RNBM14",
"state" : "RELEASED"
}
My query should return the handle of the last document alone .ie, document with the status only with the RELEASED status .i am stuck, I really appreciate your ideas to improve this.
From Your question,i understand that you want all state ='Released' ans state!= 'BOOKED' which i think you have written little incorrect.
MongoDB query:
db.inventory.find({'state' : 'RELEASED'}})
Also go through mognodb docs
I hope it will help.I am also new to mongodb,if there is an error please make it correct.
I'm using firebase4j (a firebase library for Java, I know it is much better to go with node, I just wanted to try to do it with Java). In my database I need to persist the url of images with a bunch of the picture's information. The thing is that the picture url itself is very deep into the JSON
"users" : {
"aCategory" : {
"aUser" : {
"photos" : {
"photoUid1" : [ {
"value1" : false,
"value2" : "qwerty",
"score" : 40,
"url" : "http://someurl.com"
}
That is why I am trying to create an index for the pictures ordered by score, containing the url pointing to the location of the photo object in the firebase database. Here is where the issue begins. Firebase4j does not let you push, to a list for example, so the index ends up with this format:
{
"-UID1": {
"firebaseImgUrl": "users/aCategory/aUser/photos/photoUid1",
"score": 31
},
"-UID2": {
"firebaseImgUrl": "users/aCategory/aUser/photos/photoUid2",
"score": 30
}
}
I already added the rule ".indexOn" in order for firebase to answer with the right photos when asked for http://firebaseurl.com/users/...?orderBy="score"&limitToFirst=10, which is what I'm doing. I would like to know how should I iterate a JSON object of object as shown in the example above. I'm receiving the data from an Angular 4 client. I've tried a number of methods which haven't worked for me:
result: Photo[] = [];
for(let key in json){
console.log(key); //prints the UIDs
console.log(key.url); //url is not a property of string
//thus
result.push(new Photo(key.url, key.score)); //not working
}
The key is only a string, indicating the keys in your json. You should use it to access your object, like this:
result: Photo[] = [];
for(let key in json){
result.push(new Photo(json[key].firebaseImgUrl, json[key].score));
}
I have a collection of users:
> db.users.find().pretty()
{
"_id" : ObjectId("544ab933e4b099c3cfb62e12"),
"token" : "8c9f8cf4-1689-48ab-bf53-ee071a377f60",
"categories" : [
DBRef("cue_categories", ObjectId("544ab933e4b099c3cfb62e10")),
DBRef("cue_categories", ObjectId("544ab933e4b099c3cfb62e11"))
]
}
I want to find all users who have (let's say) ObjectId("544ab933e4b099c3cfb62e10") category and remove it (because this category was deleted and I don't want users to refer to it anymore).
The valid query to do it in JSON format would be:
db.users.update({
categories:{
$in:[
DBRef("cue_categories", ObjectId("544ab933e4b099c3cfb62e10"))
]
}
},
{
$unset:{
"categories.$":true
}
})
Here's a Spring mongodb query:
Query query = new Query();
query.addCriteria(Criteria.where("categories.$id").in(categoryIds));
Update update = new Update();
update.unset("categories.$");
operations.updateMulti(query, update, User.class);
In order to make an appropriate DB reference I have to provide a list of category IDs, each category ID (in categoryIds) is an instance of org.bson.types.ObjectId.
The problem is that the result query turns out to be without a positional operator:
DEBUG o.s.data.mongodb.core.MongoTemplate - Calling update using
query: { "categories.$id" : { "$in" : [ { "$oid" :
"544ab933e4b099c3cfb62e10"}]}} and update: { "$unset" : { "categories"
: 1}} in collection: users
So the update part must be { "$unset" : { "categories.$" : 1}}
P.S.
I managed to get around by falling back to the plain Java driver use
DBObject query = new BasicDBObject("categories.$id", new BasicDBObject("$in", categoryIds));
DBObject update = new BasicDBObject("$unset", new BasicDBObject("categories.$", true));
operations.getCollection("users").updateMulti(query, update);
But my question still remains open!
P.S.S.
My case is very similar to Update Array Field Using Positional Operator ($) Does Not Work bug and looks like it was fixed for versions 1.4.1 and 1.5. That being said I use spring-data-mongodb version 1.5.1. And I'm confused. Does anybody have a clue?
You can not use positional $ operator with unset as per MongoDB documentation. It will set the value as Null. https://docs.mongodb.com/manual/reference/operator/update/positional/
I use mongoDB to collect comments inside a collection comments
I use this java programme to create them
...
BasicDBObject comment=new BasicDBObject();
BasicDBObject auteur=new BasicDBObject();
auteur.put("id", id);
auteur.put("login", login);
auteur.put("contact",false);
comment.put("auteur",auteur);
comment.put("texte",texte);
...
When i try to find the comment using the field texte it works:
db.comments.find({"texte":"my name is user1"})
{
"_id" : ObjectId("5341395ae4b082f5895d5967"),
"auteur" : { "id" : 1, "login" : "user1", "contact" : false },
"texte" : "my name is user1"
}
However my aim is to find them by using the the field id of auteur.
I tried
db.comments.find({"auteur":{"id":1}})
but it returns nothing...
I'm really lost. Thanks!!
You would use the Dot Notation to access the id of the sub document auteur:
db.comments.find({"auteur.id": 1});
The dot notation can also be used to access an element of an array by the zero-based index position:
db.things.find({"an_array_name.15": "a text to search..."});
Regards.
Mohamed.