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/
Related
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 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);
This post if a follow-on from my previous question:
Apache Lucene - Optimizing Searching
I want to create an index from title stored in my database, store the index on the server from which I am running my web application, and have that index available to all users who are using the search feature on the web application.
I will update the index when a new title is added, edited or deleted.
I cannot find a tutorial to do this in Apache Lucene, so can anyone help me code this in Java (using Spring).
From my understanding to your question, you need to do the following :
1) Index you data (titles in your case)
first you need to implement the code that create that index for you data, check this sample of code.
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
// Store the index in memory:
//Directory directory = new RAMDirectory();
Store an index on disk
Directory directory = FSDirectory.open(indexfilesDirPathOnYourServer);
IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_CURRENT, analyzer);
IndexWriter iwriter = new IndexWriter(directory, config);
Document doc = new Document();
String title = getTitle();
doc.add(new Field("fieldname", text, TextField.TYPE_STORED));
iwriter.addDocument(doc);
iwriter.close();
here you need to loop over you all data.
2) Search for you indexed data.
you can search for you data by using this code:
DirectoryReader ireader = DirectoryReader.open(indexfilesDirPathOnYourServer);
IndexSearcher isearcher = new IndexSearcher(ireader);
// Parse a simple query that searches for "text":
QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "fieldname", analyzer);//note here we used the same analyzer object
Query query = parser.parse("test");//test is am example for a search query
ScoreDoc[] hits = isearcher.search(query, null, 1000).scoreDocs;
// Iterate through the results:
for (int i = 0; i < hits.length; i++) {
Document hitDoc = isearcher.doc(hits[i].doc);
System.out.println(hitDoc.get("fieldname"));
}
ireader.close();
directory.close();
Note : here you don't have to fetch all the data from your DB, you can directly get it from index. also you don't have to re-create the whole index each time user search or fetch the data, you can update the title from time to time when you add/update or delete one by one (the title that have been updated or deleted not the whole indexed titles).
to update index use :
Term keyTerm = new Term(KEY_FIELD, KEY_VALUE);
iwriter.updateDocument(keyTerm, updatedFields);
to delete index use :
Term keyTerm = new Term(KEY_FIELD, KEY_VALUE);
iwriter.deleteDocuments(keyTerm);
Hope that help you.
I have collection of documents (say 10 documents)and i'm indexing them this way, by storing the term vector
StringReader strRdElt = new StringReader(content);
Document doc = new Document();
String docname=docNames[docNo];
doc.add(new Field("doccontent", strRdElt, Field.TermVector.YES));
IndexWriter iW;
try {
NIOFSDirectory dir = new NIOFSDirectory(new File(pathToIndex)) ;
iW = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_35,
new StandardAnalyzer(Version.LUCENE_35)));
iW.addDocument(doc);
iW.close();
}
After Index all the documents, i'm getting the termfrequencies of each document this way
IndexReader re = IndexReader.open(FSDirectory.open(new File(pathToIndex)), true) ;
TermFreqVector termsFreq[]; //size of number of documents
for(int i=0;i<noOfDocs;i++){
termsFreq[i] = re.getTermFreqVector(i, "doccontent");
}
my problem is i'm not getting the termfreqncy vector correspondingly. Say for 2nd document that I have indexed i'm getting it's corresponding termfrequncies and terms at "termsFreq[9]"
What is the reason for that?, how can I get the corresponding termfrequncies by the order that I have indexed the documents?
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"))
));