I want to select a specific field of a document in Mongodb collection and convert it to java object.
My document is like this:
{
"Name":"Ben",
"template":"A fingerprint template which I extracted"
}
So I wish select this "template field"
My sample code is below:
List<Document> documents = (List<Document>) collection.find().into(new ArrayList<Document>());
for (Document document : documents) {
Document doc = documents.get(document);
FingerprintTemplate template = (FingerprintTemplate) doc.get("template");
And the error is:
java: incompatible types: org.bson.Document cannot be converted to int
Any idea or any suggestions please!!
You can query if the field exists:
collection.find("template": { $exists: true, $ne: null } });
For the mapping part, you can have a look at objectMapper to map directly to a java object: https://www.baeldung.com/jackson-object-mapper-tutorial
Your error is still that you have a Document and Java is expecting an int.
Try this :
BasicDBObject query = new BasicDBObject();
BasicDBObject whereQuery = new BasicDBObject();
basicDBObject.put("template",1);
DBCursor cursor = collection.find(query,whereQuery);
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
This would print the documents that have template but to convert to Object you would need some JSON Object mapper maybe jackson
Related
I'm trying to insert a single ArrayList containing JSONS into a mongodb collection with this,
MongoClient mongo = new MongoClient("localhost", 27017);
DB db = mongo.getDB("structure");
DBCollection collection = db.getCollection("chapter");
List<Document> data = new ArrayList<>();
collection.insertMany(data);
String str = "[{\"id\":1,\"data\":\"data1\"},{\"id\":2,\"data\":\"data2\"}]";
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?
Insert ArrayList mongodb
The question above is about bulk insert of JSONS, not as a single one.
My question is unique
The exception gives a hint of what the problem is: a list cannot be used as a record (or a map-like data structure).
To quote the MongoDB documentation on documents that compose a collection:
Document Structure
MongoDB documents are composed of field-and-value
pairs and have the following structure:
{
field1: value1,
field2: value2,
field3: value3,
...
fieldN: valueN
}
So what you need to do, in your case, because you just want to insert many documents in one call, is to use collection.insertMany:
List<Document> documents = ...; //convert your list to a List<Document>
collection.insertMany(documents);
Have a look at this
https://docs.mongodb.com/manual/reference/method/db.collection.insertMany/
List<DBobject> data = new ArrayList<>();
Colletions.insertMany(data);
I am trying to query a mongodb collection and retrieve certain documents based on a field value but also only retrieve a single field per record. I tried the following but no getting the solution I want:
MongoCollection<Document> collection =
database.getCollection("client_data");
//Document document = collection
// .find(new BasicDBObject("sampleUser", "myDb"))
//.projection(Projections.fields(Projections.include("address"),
//Projections.excludeId())).first();
BasicDBObject aQuery = new BasicDBObject();
aQuery.put("clientId",567);
FindIterable<Document> iterDoc = collection.find(aQuery);
The following retrieves all documents for clientid = 567, but I only want to show the address field.
The commented out code was also what I tried but not sure how to combine that with the query.
EDIT:
I am now able to iterate through all the results but would like to parse each document; I tried parsing the document into my class object but it immediately gives an error:
Unrecognized field "_id" (class
model.Client), not marked as ignorable
But _id is the very first field in the document:
Document{{_id=6216a7f64cedfd00011c35a5,
So I tried something else rather using the first document but then I don't know how to get the next document:
while(cursor.hasNext()) {
// System.out.println(cursor.next().toJson());
Client client = new Client();
try {
JsonParser jsonParser = new JsonFactory().createParser(cursor.next().toJson());
ObjectMapper mapper = new ObjectMapper();
ObjectNode rootNode = mapper.createObjectNode();
String customerInfo = fi.first().toJson();
JsonNode jobj = mapper.readTree(customerInfo);
// this gives the error// client = mapper.readValue(jsonParser,Client.class);
client.setId(jobj.path("_id").path("$oid").asText());
Please advise.
In order to:
retrieves all documents for clientid = 567, but I only want to show the address field
You would execute the following:
collection
.find(Filters.eq("clientId", 567))
.projection(Projections.fields(
Projections.include("address"),
Projections.excludeId())
).first()
Breaking it down:
.find(Filters.eq("clientId", 567)): apply the predicate 'where clientId = 567'
.projection(Projections.fields(Projections.include("address"), Projections.excludeId())): let the response include the address field and exclude the _id field
I have the following query which I am trying to implement in Java (I am using 3.4.2 mongo-java driver) :
Json:
{
"_id" : "Team:2334918",
"fieldName" : [
"Delivery",
"Support"
],
"isDeleted" : false
}
Here the query:
db.myCollection.find({$nor: [{“fieldName”: {$exists: false}},{“fieldName”:{$size:0}}]})
I have written the following code to implement the above query:
MongoClient mc = ctm.getMongoConn();
db = ctm.getDatabase(mc);
col = db.getCollection(collectionName);
BasicDBObject searchObject = new BasicDBObject();
List<BasicDBObject> searchArguments = new ArrayList<BasicDBObject>();
searchArguments.add(new BasicDBObject("fieldName",new BasicDBObject("$exists",false)));
searchArguments.add(new BasicDBObject("fieldName",new BasicDBObject("$size",0)));
searchObject.put("$nor", searchArguments);
MongoCursor<Document> curs = (MongoCursor<Document>) col.find(searchObject);
while (curs.hasNext()){
Document doc = curs.next();
Object name1 = doc.get("fieldName");
System.out.println(name1.toString());
j++;
}
I am getting the following error while running:
java.lang.ClassCastException: com.mongodb.FindIterableImpl cannot be cast to com.mongodb.client.MongoCursor
Replace this:
MongoCursor<Document> curs = (MongoCursor<Document>) col.find(searchObject);
while (curs.hasNext()) {
}
With this:
FindIterable<Document> docs = col.find(searchObject);
for (Document d : docs) {
}
The suggestion from #Veeram (in the comments above) is correct too.
Try
MongoCursor<Document> curs = col.find(searchObject).iterator(); to get cursor.
You don't have to get hold of cursor. You can use the methods provided in the FindIterable which iterates the cursor for you. example at the end.
Also you are mixing Document (3.x) and BasicDBObject (2.x). You can replace your search builder with
Filters searchObject = Filters.nor(Filters.exists("fieldName"), Filters.size("fieldName", 0);
FindIterable<Document> curs = col.find(searchObject);
curs.forEach();
More info here by the author.
I have the following code:
#RequestMapping(value = "/envinfo", method = RequestMethod.GET)
#ResponseBody
public Map getEnvInfo()
{
BasicQuery basicQuery = new BasicQuery("{_id:'51a29f6413dc992c24e0283e'}", "{'envinfo':1, '_id': false }");
Map envinfo= mongoTemplate.findOne(basicQuery, Map.class, "jvmInfo");
return envinfo;
}
As you can notice, the code:
Retrieves JSON from MongoDB
Converts it to a Map object
The Map object is then converted to JSON by Spring MongoData before it is returned to the browser.
Is it possible to directly return the raw json from MongoDb without going through the intermediate conversion steps?
There's two way's you can do this right now:
1. Using the CollectionCallback on MongoTemplate
You can use a CollectionCallback to deal with the returned DBObject directly and simply toString() it:
template.execute("jvmInfo", new CollectionCallback<String>() {
String doInCollection(DBCollection collection) {
DBCursor cursor = collection.find(query)
return cursor.next().toString()
}
}
Yo'll still get the exception translation into Spring's DataAccessExceptions. Note, that this is slightly brittle as we expect only a single result to be returned for the query but that's probably something you have to take care of when trying to produce a String anyway.
2. Register a Converter from DBObject to String
You can implement a Spring Converter to do the toString() for you.
class DBObjectToStringConverter implements Converter<DBObject, String> {
public String convert(DBObject source) {
return source == null ? null : source.toString();
}
}
You can then either use the XML configuration or override customConversions() to return a new CustomConversions(Arrays.asList(new DBObjectToStringConverter())) to get it registered with your MongoConverter. You can then simply do the following:
String result = mongoTemplate.findOne(basicQuery, String.class, "jvmInfo");
I will add the just showed converter to Spring Data MongoDB and register it by default for the upcoming 1.3 GA release and port the fix back to 1.2.x as part of the fix for DATAMONGO-743.
As Oliver points out, you can use Spring Data for that, but an alternative which you may or may not prefer would be to use MongoDB's more low-level Java Driver. Take a look at the MongoDB Java Driver 3.x or MongoDB Java Driver 2.x documentation for instructions on using that driver.
Basically, what you need to do is this:
MongoDB Java Driver 3.x
MongoClient mongoClient = new MongoClient();
MongoDatabase db = mongoClient.getDatabase("test");
MongoCollection coll = db.getCollection("testCollection");
BasicDBObject query = new BasicDBObject("_id", "51a29f6413dc992c24e0283e");
try (MongoCursor<Document> cursor = collection.find(query).iterator()) {
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
}
MongoDB Java Driver 2.x
MongoClient mongoClient = new MongoClient();
DB db = mongoClient.getDB("test");
DBCollection coll = db.getCollection("testCollection");
BasicDBObject query = new BasicDBObject("_id", "51a29f6413dc992c24e0283e");
try (DBCursor cursor = coll.find(query)) {
while(cursor.hasNext()) {
System.out.println(cursor.next());
}
}
That will print out all the documents in the collection that have a field _id with a value 51a29f6413dc992c24e0283e.
For me the following worked perfectly:
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.bson.Document;
List<Document> documents = mongoTemplate.find(query, Document.class, "collection_name");
With the driver Java Mongodb, I am looking for a way to return just restricted fields with a
find() or findOne().
For example, I have a collection "people" with fields : "id", "name", "surname", "address", "city"... and I just want to return "name" and "surname"
I searched on the Web and I just found this example of code Java Mongodb : http://vsbabu.org/mt/archives/2010/03/02/simple_mongodbjava_example.html
If you are using Java Driver 3.1, you can use Projections:
collection.find().projection(Projections.include("name", "surname"));
You can pass another DBObject with the names of the fields and pass it here:
cur = coll.find(new BasicDBObject("id", 6655), your_dbobject_with_field_names);
Here is the API documentation
This codes will handle your problem.(java driver 3.0.2)
BasicDBObject fields = new BasicDBObject();
fields.put("title", 1);
DBCursor cursor = collection.find(new BasicDBObject(),fields).sort(new BasicDBObject("_id", 1));
this code run for me:
String json = "{_id:0,name:1,surname:1}";
Bson bson = BasicDBObject.parse( json );
FindIterable<Document> iterDoc = collection.find().projection(bson);