I'm using mongo mongo java driver version 2.11.2. I want to insert some few documents into my dbin mongodb and when I try to do it from command line it all works fine. But when I use mongo java driver, it is not working. I'm using BasicDBObject to populate the document. But collection.insert(BasicDBObject).getN() gives me 0 always. Nothing is getting inserted into the collection. Am I missing something here?
Adding the code:
mongo = new MongoClient("localhost", 27017);
DB db = mongo.getDB("db");
DBCollection collection = db.getCollection("collection");
BasicDBObject o = new BasicDBObject();
o.put("key1", "value1");
o.put("key2", "value2");
collection.insert(o);
No update is made in DB after this.
The 'n' value from the getlasterror of an insert is always zero. (The 'n' value is what the WriteResult.getN() returns.)
See this MongoDB Jira ticket: https://jira.mongodb.org/browse/SERVER-4381. Which has been closed in preference to a new insert, update, remove mechanism: https://jira.mongodb.org/browse/SERVER-9038
Long story short. You are not mad or missing anything. It is a "feature" of MongoDB that will hopefully finally be fixed with the 2.6 release.
Rob.
Edit:
I modified your example slightly to print the saved document. Can you try running this version in your environment?
import java.net.UnknownHostException;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.MongoClient;
import com.mongodb.WriteConcern;
public class StackOverFlow {
public static void main(String[] args) throws UnknownHostException {
MongoClient mongo = new MongoClient("localhost:27017");
DB db = mongo.getDB("db");
DBCollection collection = db.getCollection("collection");
BasicDBObject o = new BasicDBObject();
o.put("key1", "value1");
o.put("key2", "value2");
collection.insert(WriteConcern.SAFE, o);
for (DBObject doc : collection.find()) {
System.out.println(doc);
}
}
}
On my machine it outputs:
{ "_id" : { "$oid" : "5235f98495302901eb70e7a4"} , "key1" : "value1" , "key2" : "value2"}
Related
my doc in elsticsearch is like below
"hits" : [
{
"_index" : "MyIndex",
"_type" : "_doc",
"_id" : "Lxh7THMBycWRIeJFdwbZ",
"_score" : 1.0,
"_source" : {
"#timestamp" : "2020-07-14T13:10:26.087+0430",
"message" : "elk: customer inserted: id=5",
"traceId" : "ABC",
"severity" : "INFO",
"thread" : "http-nio-8095-exec-2"
}
}
]
I want to delete All docs in one index that "traceId" : "ABC" with java code.
I use Elasticsearch 7.8 and my client is RestHighLevelClient.
please guide me.
The below sample code should help. You can refer to the links below to go through the API and understand what needs to be done in steps.
Basically every request sent via Java would have below two parts.
Something similar to HttpClient for every request sent to elasticsearch i.e. High Level Rest Client.
API Specific Query which in our case is Delete by Query
As for your example, note that I'm assuming that traceId.keyword is the field of type keyword and hence I'm using TermBuilder i.e. Term Query. If it is of type text I've mentioned Match Query in the comment, you would have to use that.
Sample Code
import java.io.IOException;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.reindex.BulkByScrollResponse;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
public class DeleteBasedOnQuery {
public static void main(String[] args) throws IOException {
RestHighLevelClient client = new RestHighLevelClient(
RestClient.builder(new HttpHost("localhost", 9200, "http")));
deleteQueryUsingMatch(client);
client.close();
}
private static void deleteQueryUsingMatch(RestHighLevelClient client) throws IOException {
//Mention index name
DeleteByQueryRequest request = new DeleteByQueryRequest("my_delete_index");
request.setConflicts("proceed");
request.setBatchSize(100);
request.setRefresh(true);
//Term Query to Delete the document. Note the field name and value in below code
request.setQuery(new TermQueryBuilder("traceId.keyword", "ABC"));
//Match Query to Delete the Document
//request.setQuery(QueryBuilders.matchQuery("traceID", "abc"));
//Execute the request to delete based on above details
BulkByScrollResponse bulkResponse = client.deleteByQuery(request, RequestOptions.DEFAULT);
//By this time your delete query got executed and you have the response with you.
long totalDocs = bulkResponse.getTotal();
long deletedDocs = bulkResponse.getDeleted();
//Print the response details
System.out.println("Total Docs Processed :: " + totalDocs);
System.out.println("Total Docs Deleted :: " + deletedDocs);
}
}
im new to MongoDB and completely confused by the queries. I simply need to update a document in a mongodb database by adding a string value (example: Temperature) to a list of strings. From research I know that I have to use the $push method for that. I think the code has to look somehow like this:
BasicDBObject newDocument = new BasicDBObject().append("$set",
new BasicDBObject().append("Subscribed Topics", topic));
collection.update(new BasicDBObject().append("Sensor Type", sensorType), newDocument);
new BasicDBObject("$push",
new BasicDBObject("Subscribed Topics", topic));
The field with the array is called "Subscribed Topics", "topic" is a String (Temperature). Then I want to update the document in the collection with the corresponding "Sensor Type". However, I do not really know how to call the $push part correctly. I hope someone can help me sort this part of the code.
Best regards.
Update, I tried to implemented as suggested in the duplicate question but still got error. Very unsure if thats the right way anyway.
DBObject listItem = new BasicDBObject("Subscribed Topics", "Light");
DBObject updateQuery = new BasicDBObject("$push", listItem);
collection.update(query, updateQuery);`
I create a new Object with the value Light in for Key Subscribed Topics (the array). Why do I push it to a new Object then?
My goodness! This question got me descending into the long forgotten world of Java again - after all these years... ;) Anyhoo, here's a complete working example that might give you a clue of what's going on. You can run the code several times and see how the number of elements in the "Subscribed Topics" array increases.
I used the following driver: https://oss.sonatype.org/content/repositories/releases/org/mongodb/mongo-java-driver/3.3.0/mongo-java-driver-3.3.0.jar
import com.mongodb.MongoClient;
import com.mongodb.client.MongoDatabase;
import com.mongodb.client.MongoCollection;
import org.bson.Document;
import org.bson.conversions.Bson;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Updates.*;
public class MongoDbPush {
public static void main(String[] args)
{
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("pushExampleDb");
MongoCollection<Document> collection = database.getCollection("pushExampleCollection");
String sensorType = "Temperature";
// try to load existing document from MongoDB
Document document = collection.find(eq("Sensor Type", sensorType)).first();
if(document == null)
{
// no test document, let's create one!
document = new Document("Sensor Type", sensorType);
// insert it into MongoDB
collection.insertOne(document);
// read it back from MongoDB
document = collection.find(eq("Sensor Type", sensorType)).first();
}
// see what it looks like in JSON (on the first run you will notice that it has got an "_id" but no "Subscribed Topics" array yet)
System.out.println(document.toJson());
// update the document by adding an entry to the "Subscribed Topics" array
Bson filter = eq("Sensor Type", sensorType);
Bson change = push("Subscribed Topics", "Some Topic");
collection.updateOne(filter, change);
// read one more time from MongoDB
document = collection.find(eq("Sensor Type", sensorType)).first();
// see what the document looks like in JSON (on the first run you will notice that the "Subscribed Topics" array has been created and has got one element in it)
System.out.println(document.toJson());
mongoClient.close();
}
}
The above method still works, however, with updated Mongo Driver the below is also a viable mechanism.
The below works for Mongo Driver 3.6 onward (in this case using 3.12.4)
MongoClient mongoClient = new MongoClient();
MongoDatabase database = mongoClient.getDatabase("pushExampleDb");
MongoCollection<Document> collection = database.getCollection("pushExampleCollection");
collection.findOneAndUpdate(Filters.eq("Sensor Type",<theSensorTypeNameComesHere>),
Updates.pushEach("Subscribed Topics",<listContainingTheValuesComeHere>));
Refer: $push and $each from MongoDB Manual
I would like to create method that composes db query using optional query parts.
In old days I could write method like:
import com.mongodb.DBObject;
import com.mongodb.QueryBuilder;
public DBObject createQuery(Optional<String> aOpt, Optional<Integer> bOpt) {
QueryBuilder builder = new QueryBuilder();
aOpt.ifPresent(a -> builder.and("a").is(a));
bOpt.ifPresent(b -> builder.and("b").lessThan(b));
return builder.get();
}
how to accomplish it with new MongoDB Java driver 3.0
I tried something like
import org.bson.Document;
import com.mongodb.client.model.Filters;
public Document createQuery(Optional<String> aOpt, Optional<Integer> bOpt) {
Document query = new Document();
aOpt.ifPresent(a -> query.put("a", a));
bOpt.ifPresent(b -> query.[nonExistingMethod](Filters.lt("b", b)));
return query;
}
But all filters methods returns BSON which could not be converted to Document fluently. It seems that Filters could not be used that way... pretty useless.
Do I miss something.
How to do it wisely?
I have a mongodb database, I need to insert text data values eg(date time PH value) every 3 hours automatically using java.
Need help
I have made a mongodb database called project and collection called Water Monetering system
also here is the basic layout of java- mongodb integration
import com.mongodb.MongoClient;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.DBCursor;
import com.mongodb.ServerAddress;
import java.util.Arrays;
public class MongoDBJDBC{
public static void main( String args[] ){
try{
// To connect to mongodb server
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
// Now connect to your databases
DB db = mongoClient.getDB( "project" );
System.out.println("Connect to database successfully");
DBCollection coll = db.getCollection("WaterMoneteringSystem");
System.out.println("Collection WaterMoneteringSystem selected successfully");
BasicDBObject doc = new BasicDBObject("title", "Watermoneteringsystem").
append("Date", "date").
append("time", "time").
append("value", "ph").
coll.insert(doc);
System.out.println("Document inserted successfully");
}catch(Exception e){
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}
}
I am not getting how data(date time PH) in text box can be implemented
Thank you
Instead of:
BasicDBObject doc = new BasicDBObject("title", "Watermoneteringsystem").
append("Date", "date").
append("time", "time").
append("value", "ph");
You need something like:
BasicDBObject doc = new BasicDBObject("title", "Watermoneteringsystem").
append("Date", new Date()).
append("value", "ph");
The new Date() call will set today's date and time in there (you don't need separate fields for date and time).
But the "ph" bit needs to come from some other place - where are you getting the ph values from? Is it going to be an argument (i.e. in args[])? Is it coming from a file, or external system?
Assuming it's something you can pass in to the method, you can do something like:
String phValue = args[0];
BasicDBObject doc = new BasicDBObject("title", "Watermoneteringsystem").
append("Date", new Date()).
append("value", phValue);
I'd suggest renaming the field to something like "ph" or "phValue" as well, since "value" is not a helpful field name.
Take a look at the MongoDB and Java documentation, there are more examples there in how to use MongoDB from Java.
I'm trying to query from one collection and insert into another using the Java API, but I'm getting an exception I don't understand:
Exception in thread "main" java.lang.IllegalArgumentException: can't save partial objects
at com.mongodb.DBCollection._checkObject(DBCollection.java:1380)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:222)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:205)
at com.mongodb.DBCollection.insert(DBCollection.java:57)
at com.mongodb.DBCollection.insert(DBCollection.java:100)
Is there some "finalize" method I need to call on the document or something? My code goes like this:
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
Mongo mongo = new Mongo("mongodb://...");
DB db = mongo.getDB("foo");
DBCollection rawCollection = db.getCollection("foo1");
DBCollection aggCollection = db.getCollection("foo2");
DateTimeZone tz = DateTimeZone.forOffsetHours(-5);
BasicDBObject toGrab = new BasicDBObject("Time1", 1).append("col2", 1).append("col3", 1);
DBCursor c = rawCollection.find(null, toGrab).limit(10);
for (DBObject doc : c) {
Date newDate = new DateTime( ((BasicBSONObject) doc).getDate("Time1") )
.withZone(tz).monthOfYear().roundCeilingCopy()
.withZone(DateTimeZone.UTC).toDate();
doc.put("Time2", newDate);
aggCollection.insert(doc);
}
You are querying for specific fields using collection.find(query,projection)
By specifying projection in the arguments to a find operation, the collection is returning you a partial object.
From the posted stack trace, when calling 'insert', the underlying API is running _checkObject(doc), which throws the exception for a "partial object", as this is the same instance returned by cursor.
You could get around this by creating (new BasicDBObject(doc)) effectively copying the returned partial object, and then saving the copy to the aggCollection..
BasicDBObject doc = ...;
BasicDBObject copyOfDoc = new BasicDBObject(doc);
copyOfDoc.put("Time2", newDate);
aggCollection.insert(copyOfDoc);
See Find and the collection source and the map constructor.