I am trying to set multiple fields with an update in MongoDB using Java
DBObject nameQuery = new BasicDBObject();
nameQuery.put(DBUser.LAST_SEEN_NAME_FIELD, player.getName());
nameQuery.put(DBUser.LAST_SEEN_NAME_LOWER_FIELD, player.getName().toLowerCase());
nameQuery.put(DBUser.UUID_FIELD, new BasicDBObject("$ne", Database.makeStorableUUID(player.getUniqueId())));
DBObject updateFields = new BasicDBObject();
updateFields.put(DBUser.LAST_SEEN_NAME_FIELD, "");
updateFields.put(DBUser.LAST_SEEN_NAME_LOWER_FIELD, "");
DBObject nameUpdate = new BasicDBObject("$set", updateFields);
this.update(nameQuery, nameUpdate);
When this runs it doesn't throw any errors but I would assume there is something wrong with my query or update. I'm hoping someone can point me in the right direction.
I fixed the problem by using updateMulti instead of update.
Related
I'm using MongoDB 3.2 and MongoDB Java Driver 3.2. In order to query document I use the following code:
Document query = new Document("fetchStatus", new Document("$lte", fetchStatusParam));
ArrayList<Document> unfetchedEvents = dbC_Events.find(query).into(new ArrayList<Document>());
This query works but the problem is that in this case all fields of the document are retrieved (analog of select * in SQL). In order to optimize query performance, I want to specify fields I really need and fetch only them.
I found couple of examples, such as:
BasicDBObject query = new BasicDBObject();
BasicDBObject fields = new BasicDBObject("Name", 1);
coll.find(query, fields);
but all of them are designed for outdated version of MongoDB Java Driver, e.g. 2.4, while I'm using 3.2.
How can I query only specific fields of document in MongoDB Java Driver 3.2?
There is a .projection() method that is chainable to the query result which allows you to specify fields.
Either expressed as a document, with the familiar and well documented BSON syntax:
ArrayList<Document> unfecthedEvents = collection.find(
new Document("fetchStatus", new Document("$lte", fetchStatusParam))
).projection(
new Document("Name",1)
).into(new ArrayList<Document>());
Or as a fields property builder which really just translates to exactly the same BSON:
ArrayList<Document> unfecthedEvents = collection.find(
new Document("fetchStatus", new Document("$lte", fetchStatusParam))
).projection(
fields(include("Name"))
).into(new ArrayList<Document>());
It worked for me as well:
BasicDBObject whereQuery = new BasicDBObject();
BasicDBObject fields = new BasicDBObject();
// the conditions in where query
whereQuery.put("dzeeClient", dzeeClient);
whereQuery.put("recommendationRunType", planView);
whereQuery.put("recommendedPlans.enrolled",employeeViewed);
// the fields to be returned from the query-only loginId, and remove _id
fields.put("loginId", 1);
fields.put("_id", 0);
FindIterable<Document> cursor = collection.find(whereQuery)
.projection(fields).sort(new BasicDBObject("timeStamp",-1)).limit(1);
I'm using MongoDB 3.2 and MongoDB Java Driver 3.2. I want to update the value the document having its ID. In order to do that I tried to use the following two approaches (found in Stackoverflow and MongoDB Blog):
Approach #1:
for(String docID : expiredDocsIDs) {
Bson filter = Filters.eq("_id", docID);
Bson updates = Updates.set("isExpired", true);
dbCollection.findOneAndUpdate(filter, updates);
}
Approach #2:
expiredDocsIDs.stream()
.forEach(docID -> {
BasicDBObject searchQuery = new BasicDBObject("_id", docID);
BasicDBObject updateFields = new BasicDBObject();
updateFields.append("isExpired", true);
updateFields.append("fetchStatus", "FETCHED");
BasicDBObject setQuery = new BasicDBObject();
setQuery.append("$set", updateFields);
dbCollection.updateOne(searchQuery, setQuery);
});
None of these approaches does not work.
It iterates over the list of documents IDs, executes the code but at the end of the code, when I check the documents in DB there is no any change in the documents' field I tried to update.
How can I update the specific document in MongoDB?
As BlakesSeven correctly noted, the problem was with a casting of _id field. The original code sent this parameter as String while the correct way is to send a parameter of ObjectId type.
The correct and worked code form MongoDB 3.2:
this.trackedEpisodesReg.entrySet().stream()
.filter(ep -> ep.getValue().isExpired())
.forEach(ep -> {
BasicDBObject updateFields = new BasicDBObject();
updateFields.append("isExpired", true);
BasicDBObject setQuery = new BasicDBObject();
setQuery.append("$set", updateFields);
BasicDBObject searchQuery = new BasicDBObject("_id", new ObjectId(ep.getValue().getEpisodeID()));
dbCollection.updateOne(searchQuery, setQuery);
});
I have a device collection.
{
"_id" : "10-100-5675234",
"_type" : "Device",
"alias" : "new Alias name",
"claimCode" : "FG755DF8N",
"hardwareId" : "SERAIL02",
"isClaimed" : "true",
"model" : "VMB3010",
"userId" : "5514f428c7b93d48007ac6fd"
}
I want to search document by _id and then update it after removing a field userId from the result document. I am trying different ways but none of them is working. Please help me.
You can remove a field using $unset with mongo-java driver in this way:
MongoClient mongo = new MongoClient("localhost", 27017);
DB db = (DB) mongo.getDB("testDB");
DBCollection collection = db.getCollection("collection");
DBObject query = new BasicDBObject("_id", "10-100-5675234");
DBObject update = new BasicDBObject();
update.put("$unset", new BasicDBObject("userId",""));
WriteResult result = collection.update(query, update);
mongo.close();
The easiest way is to use the functionality in the java driver:
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(new ObjectId("10-100-5675234")));
Update update = new Update();
update.unset("userId"); //the fields you want to remove
update.set("putInYourFieldHere", "putInYourValueHere"); //the fields you want to add
mongoTemplate.updateFirst(query, update, Device.class);
The above code assumes that your "_id" is your mongodb normal "_id" which means that the variable you are looking for must be encased in the new ObjectId().
Long time since this post was opened, but might be useful for someone in the future.
device.updateMany(eq("_id", "whatever"), unset("userId"));
An ugly way is to replace the old version with the new version of you document (no userid).
BasicDBObject newDocument = new BasicDBObject();
newDocument.put("_type", "Device");
newDocument.put("alias", "new Alias name");
// ...
BasicDBObject searchQuery = new BasicDBObject().append("_id", "10-100-5675234");
collection.update(searchQuery, newDocument);
The MongoDB documentation provides a clear answer to this question: use the $unset update operator.
I am using a Java driver to run some mongo text searches.
An example of my previous code is (where values is a String passed in):
DBCollection coll = db.getCollection("testCollection");
//create the basic object
DBObject searchCmd = new BasicDBObject();
//create the search cmd
searchCmd.put("text", "testCollection"); // the name of the collection (string)
// define the search word
searchCmd.put("search", value); // the term to search for (string)
// define the return values
searchCmd.put("project", new BasicDBObject("score", 1).append("name", 1).append("path", 0).append("_id", 0));
// get the results
BasicDBObject commandResult = db.command(searchCmd);
// Just out the results key
BasicDBList results = (BasicDBList) commandResult.get("results");
then I loop over the "results" and I get for each it score by
// Get the number ii
BasicDBObject element = (BasicDBObject) results.get(ii);
// Now get the score
double score = (double) element.get("score");
I want to upgrade to use find since that seems the way 2.6 and later prefers it. So far I have:
DBCollection coll = db.getCollection("testCollection");
BasicDBObject query = new BasicDBObject();
query.append("$text", new BasicDBObject("$search", value));
DBCursor cursor = coll.find(query);
However, I am not sure how to get the score.
I tried doing something like:
query.append("score", new BasicDBObject("$meta", "textScore"));
But this does not work. I would like to be able to get the name and the score so that I can then insert them into a new collection that will also hold the score.
I can get the name easily by:
while (cursor.hasNext())
{
DBObject next = cursor.next();
String name = next.get("name").toString();
}
But how do I get the score?
I found this interesting page: http://api.mongodb.org/java/current/
it appears that find can take a second DBObject which has the fields.
I created a new object:
BasicDBObject fields = new BasicDBObject();
fields.append("score", new BasicDBObject("$meta", "textScore"));
and I am calling find using:
DBCursor cursor = coll.find(query, fields);
and now I can get the score the same way I can get the name.
Im using java/mongodb. I would like to create a table (collection) with some users. Well, its working im just not sure about my coding style. Could be this good if i just want to add 3 new persons to the collection?
BasicDBObject doc = new BasicDBObject();
doc.put("name", "klaus");
doc.put("age", 30);
doc.put("city", "new york");
col.insert(doc);
BasicDBObject doc2 = new BasicDBObject();
doc2.put("name", "mirko");
doc2.put("age", 23);
doc2.put("city", "madrid");
col.insert(doc2);
BasicDBObject doc3 = new BasicDBObject();
doc3.put("name", "jon");
doc3.put("age", 34);
doc3.put("city", "unknown");
col.insert(doc3);
Its look so "long". To add only 3 Persons I have to create always a new BasicDBObject and insert it with the same line code (col.insert(bla))? It cant be ^^ And an other question too: At the first time(doc) im adding name, age and city as column. Why do I have to add "name", "age" and "city" again and again... I just want to add "mirko", 23 and "madrid" for doc2.
The last thing what bugs me is that I can add a new Dokument to the Collection with the same(!) values. I could add a new jon with 34 years and the same city. Is this ok? And if yes, I would like to change it. Howto?
Thank you!
Use json for it..
String json = "{'key' : 'value'}"; /* Create json formatted data here */
DBObject dbObject = (DBObject)JSON.parse(json);
collection.insert(dbObject);
No need to execute insert several times. You can make one insert call for collection of objects:
http://api.mongodb.org/java/2.0/com/mongodb/DBCollection.html#insert(java.util.List)
For example:
List<BasicDBObject> docs = new ArrayList<BasicDBObject>();
BasicDBObject doc = new BasicDBObject();
doc.put("name", "klaus");
doc.put("age", 30);
doc.put("city", "new york");
docs.add(doc);
BasicDBObject doc2 = new BasicDBObject();
doc2.put("name", "mirko");
doc2.put("age", 23);
doc2.put("city", "madrid");
docs.add(doc2);
BasicDBObject doc3 = new BasicDBObject();
doc3.put("name", "jon");
doc3.put("age", 34);
doc3.put("city", "unknown");
docs.add(doc3);
col.insert(docs);
You can always try Morphia,a java library, for MongoDB. It lets you save, retrieve and update POJO objects as documents.
For your second query related to collections with same values, in mongoDB you have the option to use unique indexes which makes sure no two records of same values are inserted in the collection