I am trying to remove duplicates in a collection using java driver in mongodb.
I am using the code
table = db.getCollection("dummy_data_OLD");
BasicDBObject query = new BasicDBObject("url", 1)
.append("unique", true).append("dropDups", true);
table.createIndex(query);
It will create a unique index , but still duplicates present in the db.
Is there any problem in my code?
This creates an index on the fields url, unique and dropDups. When you want to create an index using options, you need to provide these as a second DBObject.
DBObject fields = new BasicDBObject("url", 1);
DBObject options = new BasicDBObject("unique", true).append("dropDups", true);
db.getCollection("dummy_data_OLD").createIndex(fields, options);
Related
I want to copy a document from one collection of mongodb to another collection (or update if exist) through java.
I don't want to append each field of existing collection and then insert to another. How can I do this?
Here are two collections, temp and national. temp has only one collection, which I have to copy to national or update if it exists.
MongoCursor<Document> cursor = db.getCollection("temp").find().iterator();
try {
Document doc = new Document(cursor.next());
Document new_doc = new Document("$set",doc);
doc.append("booking_id",cursor.next().get("booking_id"));
MongoCursor<Document> cursor1 = db.getCollection("national").find(doc).iterator();
Bson filter = Filters.eq("booking_id", args);
Bson update = Filters.elemMatch("booking_id", filter);
UpdateOptions options = new UpdateOptions().upsert(true);
national.updateOne(filter, new_doc, options);
}
finally {
cursor.close();
}
If you want replace Doc2 with Doc1 you can use replaceOne()
replaceOne() replaces the first matching document in the collection that matches the filter, using the replacement document.
https://docs.mongodb.com/v3.2/reference/method/db.collection.replaceOne/
I'm trying to add a document in another document.
I am trying to insert a new document with a timestamp as a key and light prox and temp as the content of that document into document sensor_collection.
It's logical that my code doesn't work, because I'm setting a new sensor_collection. Does anyone know how I can set a timestamp document in sensor_collection or is it adviced not to do it this way?
This is the code:
MongoCollection<Document> collection = db.getCollection(Sensor.KEY_COLLECTION);
//append sensor data to existing document
collection.updateOne(doc, new Document("$set",
new Document("sensor_collection", new Document(
String.valueOf(stamp.getCurrentTime()), new Document(
Sensor.KEY_LIGHT, sensorData.getLight())
.append(Sensor.KEY_PROX, sensorData.getProx())
.append(Sensor.KEY_TEMP, sensorData.getTemp())
))));
Currently this code overrides the timestamp that's already in the db.
If you want to append to an existing embedded collection, use $push instead of $set. The $push operator appends a specified value to an array. Something like this:
collection.updateOne(doc, new Document("$push",
new Document("sensor_collection", new Document(
String.valueOf(stamp.getCurrentTime()), new Document(
Sensor.KEY_LIGHT, sensorData.getLight())
.append(Sensor.KEY_PROX, sensorData.getProx())
.append(Sensor.KEY_TEMP, sensorData.getTemp())
))));
For more details on mongo's update operators, check this out
In the Mongodb documentation I found this:
"To specify a <field> in an embedded document or in an array, use dot notation."
I used the $set operator. And I'm setting sensor_collection.timestamp
MongoCollection<Document> collection = db.getCollection(Sensor.KEY_COLLECTION);
//append sensor data to existing document
collection.updateOne(doc, new Document("$set",
new Document("sensor_collection."+String.valueOf(stamp.getCurrentTime()),
new Document(
Sensor.KEY_LIGHT, sensorData.getLight())
.append(Sensor.KEY_PROX, sensorData.getProx())
.append(Sensor.KEY_TEMP, sensorData.getTemp())
)));
This works. Gives:
i tried to remove an embedded document without succcess.
I'm looking for the java way of following instruction:
db.games.update({'_id': 73}, {$pull: {'goals': {'goal': 4}}})
The Java documentation is pretty clear, you are just constructing BSON objects to match their respective JSON counterparts as used in the shell:
BasicDBObject query = new BasicDBObject("_id", 73);
BasicDBObject fields = new BasicDBObject("goals",
new BasicDBObject( "goal", 4));
BasicDBObject update = new BasicDBObject("$pull",fields);
games.update( query, update );
Using Bson is similar.
Bson query = new Document().append("_id", 73);
Bson fields = new Document().append("goals", new Document().append( "goal", 4));
Bson update = new Document("$pull",fields);
games.updateOne( query, update );
I am writing a Java application that retrieves and presents data from an HBase database.
When writing the Get method for retrieving a row, I would like to get all the data for that row, but exclude the value for a particular column family (the "big" column family). Note: I need to retrieve the column names (qualifiers?) in that family because they contain valuable information.
Is it possible to write a Filter for that?
I have two solutions. The first one does not work and the second one is quite slow.
First solution (using a composite filter):
HTable table = getTable();
Get get = new Get(row);
FilterList filter = new FilterList(FilterList.Operator.MUST_PASS_ONE);
FilterList subFilterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
subFilterList.addFilter(new KeyOnlyFilter());
subFilterList.addFilter(new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
filter.addFilter(subFilterList);
filter.addFilter(new FamilyFilter(CompareOp.NOT_EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
get.setFilter(filter);
retrieveAndUseResult(table, get);
This solution works neither conceptually nor in practise - but perhaps I am on the right track using a composite FilterList?
Second solution (using two gets):
HTable table = getTable();
Get get = new Get(row);
// exclude the entire "big" column family
get.setFilter(new FamilyFilter(CompareOp.NOT_EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
retrieveAndUseResult(table, get);
Get get2 = new Get(row);
// include the "big" column family, but only retrieve the key
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filterList.addFilter(new KeyOnlyFilter());
filterList.addFilter(new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
get2.setFilter(filterList);
retrieveAndUseResult(table, get2);
This works, but I would favor having to do only one get.
I ended up using a variant of the second solution - using two gets. But I used a batch get list to speed it up.
The code:
HTable table = getTable();
Get get = new Get(row);
// exclude the entire "big" column family
get.setFilter(new FamilyFilter(CompareOp.NOT_EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
Get get2 = new Get(row);
// include the "big" column family, but only retrieve the key
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
filterList.addFilter(new KeyOnlyFilter());
filterList.addFilter(new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("big"))));
get2.setFilter(filterList);
List<Get> getList = new ArrayList<Get>();
getList.add(get);
getList.add(get2);
retrieveAndUseResults(table, getList);
Is there a way in which I can modify the value of one of the keys in MongoDb via its Java Driver. I tried out the following:
someCollection.update(DBObject query, DBObject update);
someCollection.findAndModify(DBObject query, DBObject update);
But both the functions completely replace the queried document with the updated document. What is the way to update only one of the value of a particular key as in the case of using $set in the mongo shell.(apart from making a completely new Document with all fields copied and one of the fields updated).
BasicDBObject carrier = new BasicDBObject();
BasicDBObject query = new BasicDBObject();
query.put("YOUR_QUERY_STRING", YOUR_QUERY_VALUE);
BasicDBObject set = new BasicDBObject("$set", carrier);
carrier.put("a", 6);
carrier.put("b", "wx1");
myColl.updateMany(query, set);
This should work, the answer which is accepted is not right above.
Try something like this:
BasicDBObject set = new BasicDBObject("$set", new BasicDBObject("age", 10));
set.append("$set", new BasicDBObject("name", "Some Name"));
someCollection.update(someSearchQuery, set);
Also look at this example.
None of the solutions mentioned above worked for me. I realized that the query should be a Document type and not a BasicDBObject :
Document set = new Document("$set", new Document("firstName","newValue"));
yourMongoCollection.updateOne(new Document("_id",objectId), set);
Where "yourMongoCollection" is of type "MongoCollection" and "objectId" of type "ObjectId"
The previous answer pointed me in the right direction, but the code to add a 2nd object to the update did not work for me. The following did:
BasicDBObject newValues = new BasicDBObject("age", 10);
newValues.append("name", "Some Name");
BasicDBObject set = new BasicDBObject("$set", newValues);
collection.update(someSearchQuery, set);
First, unless I want to reconfigure/reformat/"re-type" my values I'd go only with findAndModify and not update.
Here is a fully working example for c&p purposes... Enjoy:
Boolean updateValue(DB db, DBCollection collection, String id, String key, Object newValue)
{
DBCollection collection = db.getCollection(<collection name>);
// Identify your required document (id, key, etc...)
DBObject query = new BasicDBObject("_ID",<ID or key value>);
DBObject update = new BasicDBObject("$set", new BasicDBObject(key, newValue));
//These flags will guarantee that you'lls get the updated result
DBObject result = collection.findAndModify(query, null, null, false, update,true, true);
//Just for precaution....
if(result == null)
return false;
return result.get(key).equals(newValue);
}
According to the documents, $set is an alise for $addFields, so just use that:
var iterable = collection.aggregate(Arrays.asList(
Aggregates.addFields(new Field("foo", "bar"))
));