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.
Related
I'm building a Java application connected to MongoDB about films, and I want to create a ComboBox so I can populate it with the film names. My problem is the only way I have found is populating it with the full document, instead of just getting the film name.
This is what I have so far:
DBCursor films = collection.find();
while(films.hasNext()){
comboBox.addItem(films.next());
}
This is how I create the document:
DBCollection table = db.getCollection("films");
BasicDBObject document = new BasicDBObject();
document.put("title", titulo.getText());
document.put("arg", argumento.getText());
document.put("date", fecha.getText());
document.put("genres", genres);
table.insert(document);
Is there a way to use find to only get the film titles and then display only the value? Thanks in advance.
EDIT
In the supposed duplicated question, the question is related to finding a specific document based on one of its fields. That's not what I need, I need to populate a combobox with one field, but I need to get all my documents.
If you want to get only specific fields in your result set, you will need to use find(DBObject query, DBObject projection) and specify the fields to get in the projection parameter as next:
// Retrieve only the title of all the documents that can be found in the collection
DBCursor cursor = collection.find(
new BasicDBObject(), new BasicDBObject("title", Boolean.TRUE)
);
while (cursor.hasNext()) {
// Add the value of the title to the combo box
comboBox.addItem((String) cursor.next().get("title"));
}
Rather than do a find() pass in the keys you want returned. In this case I believe all you want back is the title. So this should work:
DBCursor films = collection.find({},{"_id":0,"title":1});
while(films.hasNext()){
comboBox.addItem(films.next());
}
DBObject and DBCollection are old 2.x classes.
You can try something like with 3.x driver.
import static com.mongodb.client.model.Projections.*;
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection<Document> col = db.getCollection("films");
List<String> titles = col.find().projection(fields(include("titles"), excludeId())).map(document -> document.getString("titles")).into(new ArrayList<>());
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 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.
Is there a way in the MongoDB Java driver to call the db.collection.remove(query) method that I see in the MongoDB shell documentation?
That is, I know the exact criteria that I need to find all the documents I want to delete from MongoDB, but I can't find a way to make one call to remove those records in one trip. All that I can figure out is to find the documents and then delete them one by one.
I see this
http://docs.mongodb.org/manual/reference/method/db.collection.remove/
which implies there should be a way to do it, but I can't figure out the Java calls to get me that to that call.
Thank you for your help
To remove documents with an age property of 25.
MongoClient mongo = new MongoClient(new ServerAddress("localhost", 27017));
DB db = mongo.getDB("thedb");
DBCollection collection = db.getCollection("test");
BasicDBObject query = new BasicDBObject();
query.append("age", 25);
collection.remove(query);
DBCollection and BasicDBObject are two of the most important classes in the Java API.
Also to remove specific values from you document you can use following code with Mongo Java 3.2
Document docToDelete = new Document("Designation", "SE-1");
objDbCollection.findOneAndUpdate(new Document("Company", "StackOverflow"), new Document("$unset", docToDelete));
Above code will first find document having company = StackOverflow and then unset (remove) Designation = SE-1 key/value from that document.
Add and Update Mongo
public class App {
public static void main(String[] args) {
try {
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB("yourdb");
// get a single collection
DBCollection collection = db.getCollection("dummyColl");
//insert number 1 to 10 for testing
for (int i=1; i <= 10; i++) {
collection.insert(new BasicDBObject().append("number", i));
}
//remove number = 1
DBObject doc = collection.findOne(); //get first document
collection.remove(doc);
//remove number = 2
BasicDBObject document = new BasicDBObject();
document.put("number", 2);
collection.remove(document);
//remove number = 3
collection.remove(new BasicDBObject().append("number", 3));
//remove number > 9 , means delete number = 10
BasicDBObject query = new BasicDBObject();
query.put("number", new BasicDBObject("$gt", 9));
collection.remove(query);
//remove number = 4 and 5
BasicDBObject query2 = new BasicDBObject();
List<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(5);
query2.put("number", new BasicDBObject("$in", list));
collection.remove(query2);
//print out the document
DBCursor cursor = collection.find();
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
collection.drop();
System.out.println("Done");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (MongoException e) {
e.printStackTrace();
}
How to remove duplicate values from the result of MongoDB objects?
I have some records in my mongodb as follows
{"Filename":"PHP Book.pdf","Author":"John" ,"Description":"This is my PHP Book"}
{"Filename":"Java Book.html" ,"Author":"Paul" ,"Description":"This is my JAVA Book"}
{"Filename":".NET Book.doc" ,"Author":"James" ,"Description":"This is my .NET Book"}
below is my code to search Filename and Description fields which contains "Java" word and displaying their filenames.
Mongo m = new Mongo("10.0.0.26", 27017) ;
DB db = m.getDB("soft") ;
DBCollection col = db.getCollection("poc") ;
BasicDBObject query = new BasicDBObject();
BasicDBObject query1 = new BasicDBObject();
String KeyWord="JAVA";
query.put("Filename", java.util.regex.Pattern.compile(KeyWord));
query1.put("Content", java.util.regex.Pattern.compile(KeyWord));
DBCursor cursor = col.find(query) ;
DBCursor cursor1 = col.find(query1) ;
while (cursor.hasNext()) {
DBObject o = cursor.next();
System.out.println("File name contains JAVA:"+o.get("Filename"));
}
while (cursor1.hasNext()) {
DBObject ob = cursor1.next();
System.out.println("File name whose content contains JAVA:"+ob.get("Filename"));
}
I am getting the following output:
File Name Contains JAVA:Java Book.html
File Name whose content Contains JAVA:Java Book.html
I am getting same file name from both filename and content queries.I want to remove the duplicate values.Please suggest me.
thanks
I would suggest using a $or query, something like:
DBObject query = QueryBuilder.start().or(
new BasicDBObject("Filename", java.util.regex.Pattern.compile(KeyWord)),
new BasicDBObject("Content", java.util.regex.Pattern.compile(KeyWord))).get();
and do it as a single query instead of two separate queries.
Please be advised that MongoDB will not be able to use an index for non-anchored regular expressions. See http://docs.mongodb.org/manual/reference/operator/regex/ for details.