Insert JSON Array into mongodb - java

I'm trying to insert a string that represents a JSON array into a mongodb collection with this,
String str = "[{\"id\":1,\"data\":\"data1\"},{\"id\":2,\"data\":\"data2\"},{\"id\":3,\"data\":\"data3\"}]";
DBObject dbObject = (DBObject) JSON.parse(str);
collection.insert(dbObject);
But I get the exception,
Exception in thread "main" java.lang.IllegalArgumentException: BasicBSONList can only work with numeric keys, not: [_id]
Can anyone show me the correct way to do this?

String json = "[{\"id\":1,\"data\":\"data1\"},{\"id\":2,\"data\":\"data2\"},{\"id\":3,\"data\":\"data3\"}]";
MongoCredential credential = MongoCredential.createCredential("root", "sample", "root".toCharArray());
MongoClient mongoClient = new MongoClient(new ServerAddress("localhost"), Arrays.asList(credential));
MongoDatabase db = mongoClient.getDatabase("sample");
MongoCollection<Document> collection = db.getCollection("loginTracking");
List<Document> jsonList = new ArrayList<Document>();
net.sf.json.JSONArray array = net.sf.json.JSONArray.fromObject(json);
for (Object object : array) {
net.sf.json.JSONObject jsonStr = (net.sf.json.JSONObject) JSONSerializer.toJSON(object);
Document jsnObject = Document.parse(jsonStr.toString());
jsonList.add(jsnObject);
}
collection.insertMany(jsonList);
mongoClient.close();

as per java doc the insert() can accept either single DBObject or an array or List of them.
So, in order to save, you need to convert your JSON array into an array/List of DBObjects, or save each array's item

I found a good way for achieve that:
(ArrayList<Document>) JSON.parse("[String json array]");
I had a problem with this, because i need append to this document a property that is a Json Array:
Document objAddendumVersion = new Document();
objAddendumVersion.append("_id", new ObjectId());
objAddendumVersion.append("Array", My Array here!);
But the problem is that Document.parse() doesn't work with Arrays, so i could solve it using the above line. So the final code is:
Document objAddendumVersion = new Document();
objAddendumVersion.append("_id", new ObjectId());
objAddendumVersion.append("Array", (ArrayList<Document>) JSON.parse("[String json array]"));
And it works perfect. Yes i know that exist more better ways for do that, but for the moment i'm using this.
I wait that be useful for someone with the same trouble.

Related

Update Multiple Documents on MongoDB

Currently I am on the latest version of MongoDB and coding in Java. I am trying to update multiple documents at a time, but I need to find the corresponding document first after reading from a json file. I can do this one at a time, but I have about 6million documents that I need to search and update so wanted to do this properly.
This is how the Database looks like. I am searching by lifeId
{
"_id" : "wwwww",
"mId" : "xxxxx",
"lifeId" : yyyyy
}
Below is my json file:
{
"Items":
[
{"gseid":xxxxx,"mlifeno":xxxx,"firstname":"xxx","lastname":"xxx","emailaddress1":"xxxx#hotmail.com","dateofbirth":"06-AUG-60 12.00.00.000000000 AM","phonenumber":"xxxxxx","phonetype":"Home","street1":"xxxxx","city":"xxxxx","postalcode":"xxxx","preferred":1,"addresstype":"Home"}
,{"gseid":xxxx,"mlifeno":xxx,"firstname":"xxx","lastname":"xxx","emailaddress1":"xxxx#msn.com","dateofbirth":"07-AUG-48 12.00.00.000000000 AM","phonenumber":"xxxx","phonetype":"Mobile","street1":"xxxxx","city":"xxx","postalcode":"xxx","preferred":1,"addresstype":"Home"}
,{"gseid":xxxx,"mlifeno":xxx,"firstname":"xxx","lastname":"xxx","emailaddress1":"xxx#yahoo.com","dateofbirth":"06-MAR-71 04.00.00.000000000 PM","phonenumber":"xxxx","phonetype":"Home","street1":"xxxxx","street2":"xxxxx","city":"Bolingbrook","postalcode":"xxxx","preferred":1,"addresstype":"Home"}
]
}
I loop through the json file and can insert one at a time, but what I want to know is if it's possible to insert multiple (maybe 1000 at a time). I am searching by "mlifeno" in the json file and matching it to "lifeId" in the DB.
The below code iterates through the json file items
JSONArray itemsArr = (JSONArray) itemsObj.get("Items");
for(Object temp : itemsArr){
JSONObject d = (JSONObject) parser.parse(String.valueOf((JSONObject)temp));
Long mlifeno = Long.parseLong(String.valueOf(d.get("mlifeno"))); //mlifeno
// findAndAddCol(mlifeno,database,d); //find a document by mlifeno and update the columns
}
}
The below is where I find the database document and insert, one by one (which is what I don't want)
public static void findAndAddCol(Long mlife, MongoDatabase database, JSONObject temp){
MongoCollection<Document> collection = database.getCollection("CrosswalkColl");
JsonWriterSettings prettyPrint = JsonWriterSettings.builder().indent(true).build();
Bson filter = eq("lifeId",mlife); //find document by life number
//Update profile object after all inserted into object
BasicDBObject updateFields = new BasicDBObject();
JSONObject jsonPro = new JSONObject();
JSONArray arrPro = new JSONArray();
JSONObject last = new JSONObject();
temp.forEach((key,value) -> {
//Don't add life number or gseid to profile object
if(key.toString().equals("mlifeno")){
}else if(key.toString().equals("gseid")){
//add gseid
// Bson updateOperation = set(key.toString(),value);
updateFields.append(key.toString(),value);
}else{
jsonPro.put(key.toString(),value);
}
});
updateFields.append("Profile",jsonPro);
BasicDBObject setQuery = new BasicDBObject();
setQuery.append("$set", updateFields);
//List with Batch Operation
UpdateResult updateResult = collection.updateOne(filter, setQuery); //this will search for the correct document and update
The code above works, but what I want to do is loop through maybe a 1000 at a time and bulkwrite them instead of having to do this one by one.

Is there a way to access a value of a JSON document from mongodb which is inside an ArrayList?

I have a code snippet that looks like this
MongoDatabase db = DbConnection.getDbConnection(); // connection is successfully made
MongoCollection collection = db.getCollection("candidates"); collection called candidates in the database
ArrayList<String> newList = new ArrayList<>();
FindIterable<Document> findIterable = collection.find()
.projection(fields(include("CandidateId"), excludeId()));
for(Document document:findIterable) {
newList.add(String.valueOf(document));
}
System.out.println(newList);
The output looks like this
[Document{{CandidateId=1}}, Document{{CandidateId=2}}]
Is there any way I could get an arrayList that looks like this, where i only need the value of the CandidateId field
[1,2]
You can use Document::getString like this:
newList.add(document.getString("CandidateId"));

How to extract only one value from mongoDB?

LIKE I HAVE THREE FIELD 'TO','FROM' AND 'MESSAGE', I just want to display content of message field where I have given some clause in to and from.
Document{{_id=59c7d57c674cd5673c304936, to=9915103230, from=9915103229, date=24/12/2017, message=HELLO WORLD}}
I JUST WANT TO RETRIEVE "HELLO WORLD", not the whole document.
Like I just want, String message=?????---> I need some method here so the Variable of String type gets the value Hello World.
Projection method is not working for me.
I am using JDBC MongoDB 3.5 Driver.
Use projection, the second optional argument to find(). For context, this gives you the whole document:
db.yourCollection.find({to:9915103230,from:9915103229});
This gives you only message from the results. Just name the field and set it to 1:
db.yourCollection.find({to:9915103230,from:9915103229},{message:1};
You can specify more than one thing to return:
db.yourCollection.find({to:9915103230,from:9915103229},{message:1, to:1};
Here's a functioning prog. Compile against the 3.5 drivers.
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase( "testX" );
MongoCollection<BsonDocument> coll = db.getCollection("foo", BsonDocument.class);
coll.drop();
{
BsonDocument doc = new BsonDocument();
doc.put("from", new BsonInt32(23343223));
doc.put("to", new BsonInt32(23343223));
doc.put("msg", new BsonString("hello"));
coll.insertOne(doc);
doc.remove("_id");
doc.put("from", new BsonInt32(8889));
doc.put("to", new BsonInt32(99999));
doc.put("msg", new BsonString("goodbye"));
coll.insertOne(doc);
}
{
BsonDocument query = new BsonDocument("from", new BsonInt32(8889));
BsonDocument proj = new BsonDocument("msg", new BsonInt32(1));
proj.put("_id",new BsonInt32(0));
BsonDocument d2 = coll.find(query).projection(proj).first();
System.out.println(d2);
String s2 = coll.find(query).projection(proj).first().getString("msg").getValue();
System.out.println(s2);
}

Populating combobox with document fields

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<>());

CSV to GeoJSON conversion

I want to convert a CSV line into a GeoJSON object. I am using CSVReader. Hence, nextLine[] has all the separated tokens.
I want to create BasicDBObject which has various attributes stored. I am doing it following way.
new BasicDBObject("attribute1",nextLine[0]).append("attribute2",nextLine[1])
What I want to achieve is having a document like this in MongoDB
{
attribute1: name
attribute2: address
location:{ type : "Point" ,
coordinates : [lat, long]
}
attrribute3: phonenumber
}
How do I do this using BasicDBObject?enter code here
The easiest way to do that is using the BasicDBObjectBuilder, an utility class to build DBObjects. You can do something like that:
BasicDBObject toInsert = BasicDBObjectBuilder.start()
.add("attribute1",nextLine[0])
.add("attribute2",nextLine[1])
.add(" attrribute3",nextLine[2])
.push("location")
.add("type", "Point")
.add("coordinates", new double[] { nextLine[3], nextLine[4] })
.pop()
.get()
I did it the other way
double latLong[] = new double[]{10.0, 30.0};
BasicDBObject doc = new BasicDBObject("attr1",nextLine[0])
.append("attr2", nextLine[1]
.append("location",new BasicDBObject("type","Point")
.append("coordinates",latLong))
.append("attr3", nextLine[3])
This also works as desired

Categories

Resources