Retrieve fields of all documents in mongodb collection - java

I am trying to retrieve all Fields of all Documents and embeded Documents in Mongo collection.
this is an example of one document:
{
"_id": {
"$oid": "53b309def468718462e0c390"
},
"customer": {
"companyName": "Vins et alcools Chevalier",
"contactName": "Paul Henriot",
},
"employee": {
"employeeId": 5,
"firstName": "Steven",
"lastName": "Buchanan"
},
"orderItems": [
{
"productName": "Queso Cabrales",
"unitPrice": 14,
"quantity": 12
},
{
"productName": "Singaporean Hokkien Fried Mee",
"unitPrice": 9.8,
"quantity": 10
}
],
"orderId": 10248,
"orderDate": {
"$date": "1996-07-04T07:00:00.000Z"
},
"requiredDate": {
"$date": "1996-08-01T07:00:00.000Z"
},
"shippedDate": {
"$date": "1996-07-16T07:00:00.000Z"
},
"shipVia": "Federal Shipping",
"freightCost": 32.38
}
Here is my code and output:
MongoCursor<Document> cursor;
MongoCollection<Document> collection = database.getCollection("test");
cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
//System.out.println(cursor.next().toJson());
System.out.println(cursor.next().get("key"));
}
} finally {
cursor.close();
}
And this is the out put :
null null null null null ...
i want only the Name part, but it's not working.
i'm using java driver 3.12.4 with mongodb v4.2
Tank you.

Try this:
private void printFields(){
MongoCursor<Document> cursor;
MongoCollection<Document> collection = database.getCollection("user");
cursor = collection.find().iterator();
try {
while (cursor.hasNext()) {
//System.out.println(cursor.next().toJson());
for (Map.Entry<String, Object> entry : cursor.next().entrySet())
{
System.out.println(entry.getKey() + "/" + entry.getValue());
}
}
} finally {
cursor.close();
}
}

Related

How to find distinct value with count of other array inside dhe document in MongoDB

I want to get distinct categoryCode and categoryName while this document also contains list of accessories I want to count of this accessories in the response.
Sample data:
[
{
"categoryCode":"categoryCode1",
"categoryName":"categoryName1",
"accessories":[{"a_id":1},{"a_id":2}]
},
{
"categoryCode":"categoryCod2",
"categoryName":"categoryName2",
"accessories":[{"a_id":1},{"a_id":2},{"a_id":3}]
},
{
"categoryCode":"categoryCode1",
"categoryName":"categoryNam1",
"accessories":[{"a_id":1},{"a_id":2}]
}
]
Expected result:
[
{
"categoryCode":"categoryCode1",
"categoryName":"categoryName1",
"accessoriesCount":2
},
{
"categoryCode":"categoryCod2",
"categoryName":"categoryName2",
"accessoriesCount":3
}
]
https://mongoplayground.net/p/q6AZOaTwo5a
db.collection.aggregate([
{
"$group": {
"_id": {
categoryCode: "$categoryCode",
"categoryName": "$categoryName"
},
"accessories": {
"$addToSet": "$accessories"
}
}
},
{
"$project": {
categoryCode: "$_id.categoryCode",
categoryName: "$_id.categoryName",
accessoriesCount: {
$size: "$accessories"
},
_id: 0
}
}
])
Query
group to have the distinct values
$push the accesories arrays (we dont have $concat accumulator)
reduce those arrays to union them, keep only the distinct members, and take the count.
Test code here
db.collection.aggregate([
{
"$group": {
"_id": {
"categoryCode": "$categoryCode",
"categoryName": "$categoryName"
},
"accessories": {
"$push": "$accessories"
}
}
},
{
"$set": {
"accessoriesCount": {
"$size": {
"$reduce": {
"input": "$accessories",
"initialValue": [],
"in": {
"$setUnion": [
"$$value",
"$$this"
]
}
}
}
}
}
},
{
"$project": {
"_id": 0,
"categoryCode": "$_id.categoryCode",
"categoryName": "$_id.categoryName",
"accessoriesCount": "$accessoriesCount"
}
}
])

Mongo aggregation for a DbRef field with mongoTemplate

Assume I have two mongo collections as follows.
Collection A
{
"_id" : ObjectId("582abcd85d2dfa67f44127e0"),
"level" : "super"
"dataReference" : Object
B : DbRef(B, 5b618a570550de0021aaa2ef, undefined)
}
Collection B
{
"_id" : ObjectId("5b618a570550de0021aaa2ef"),
"role" : "admin"
}
What I need is retrieve the records from Collection A, which records have "level" field's value as "super" and its related Collection B record's "role" value as "admin".
For this, I am trying to use aggregation and java mongoTemplate.
Following is the code that I tried but it returns 0 records.
final TypedAggregation<A> typedAggregation = Aggregation.newAggregation(A.class,
Aggregation.match(Criteria.where("level").equals(level)),
Aggregation.lookup("B", "_id", "dataReference.B.$id", "Basb"),
Aggregation.match(new Criteria().andOperator(
Criteria.where("B.role").regex("admin")
)));
final AggregationResults<Map> A = mongoTemplate.aggregate(typedAggregation, "A", Map.class);
Please note that I am new to Mongo aggregation.
It's quiet ugly solution:
MongoTemplate
You cannot use TypedAggregation because we need to transform A collection to be able join with B collection
Aggregation typedAggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where("level").is("super")),
new AggregationOperation() {
#Override
public Document toDocument(AggregationOperationContext context) {
return Document.parse("{\"$addFields\":{\"dataReference\":{\"$reduce\":{\"input\":{\"$objectToArray\":\"$dataReference\"},\"initialValue\":null,\"in\":{\"$cond\":[{\"$eq\":[{\"$type\":\"$$this.v\"},\"objectId\"]},\"$$this.v\",\"$$value\"]}}}}}");
}
},
Aggregation.lookup("B", "dataReference", "_id", "B"),
Aggregation.match(new Criteria().andOperator(
Criteria.where("B.role").regex("admin")
)
)
);
final AggregationResults<Document> A = mongoTemplate.aggregate(typedAggregation, "A", Document.class);
MongoDB Aggregation
db.A.aggregate([
{
"$match": {
"level": "super"
}
},
{
"$addFields": {
"B": {
"$reduce": {
"input": {
"$objectToArray": "$dataReference"
},
"initialValue": null,
"in": {
"$cond": [
{
"$eq": [
{
"$type": "$$this.v"
},
"objectId"
]
},
"$$this.v",
"$$value"
]
}
}
}
}
},
{
"$lookup": {
"from": "B",
"localField": "B",
"foreignField": "_id",
"as": "B"
}
},
{
"$match": {
"$and": [
{
"B.role": {
"$regex": "admin",
"$options": ""
}
}
]
}
}
])
MongoPlayground

Add hashmap having possible serialized JSON values to a JSON string as a node

What is the cheapest way to take the jsonstring and hashmap below and produce the result in JAVA?
pseudocode data example:
String jsonstring = {
"people": {
"name": "name1",
},
"addresses": {
"address1": {
"number": "1234",
"city": "europa"
}
}
}
HashMap hashmap = {
["string.a.1"] = "stringa1",
["string.a.2"] = "stringa2",
["object.a.1"] = "{/"item1/":/"value1/"}" // serialized JSON object
}
String result = {
"people": {
"name": "name1",
},
"addresses": {
"address1": {
"number": "1234",
"city": "europa"
}
},
"buffer": {
"string.a.1": "stringa1",
"string.a.2": "stringa2",
"object.a.1": {
"item1": "value1"
}
}
}
Thanks in advance for any help.

Trying to convert mongoDB aggregation query to java aggregation query

I am trying to convert MongoDB Aggregation function to Java Aggregation function.
My MongoDB Query is
[
{
"$match": {
"indicesId": "VUSSTAPNETFF"
}
},
{
"$unwind": "$dataSets"
},
{
"$match": {
"dataSets.date": {
"$lte": ISODate("2013-12-31T18:30:00.000Z"),
"$gte": ISODate("2008-12-31T18:30:00.000Z")
}
}
},
{
"$group": {
"_id": "$indicesId",
"mean": {
"$avg": "$dataSets.data"
},
"indices": {
"$push": "$$ROOT"
}
}
},
{
"$unwind": "$indices"
},
{
"$project": {
"_id": 1,
"mean": 1,
"firstResult": {
"$multiply": [
{
"$subtract": [
"$indices.dataSets.data",
"$mean"
]
},
{
"$subtract": [
"$indices.dataSets.data",
"$mean"
]
}
]
}
}
},
{
"$group":{
"_id":"",
"secondResult": {
"$avg": "$firstResult"
},
"mean":{
"$first": "$mean"
}
}
},
{
"$project":{
"data":{
"$sqrt":"$secondResult"
},
"mean": "$mean"
}
}
]
I tried bellow code for conversion in java.
BasicDBList subtractDBList= new BasicDBList();
subtractDBList.add("$indices.dataSets.data");
subtractDBList.add("$mean");
BasicDBList multiplyDBList= new BasicDBList();
multiplyDBList.add(new BasicDBObject("$subtract",subtractDBList));
multiplyDBList.add(new BasicDBObject("$subtract",subtractDBList));
Aggregation meanAggregation= Aggregation.newAggregation(Aggregation.match(Criteria.where(IndicesUtil.INDICES_ID).is(indicesId)),
Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.DATA_SETS),
Aggregation.match(Criteria.where(IndicesUtil.DATA_SETS_DATE).gte(startDate).lte(indicesDataSet.getDate())),
Aggregation.group(IndicesUtil.INDICES_ID).avg(averageParameter).as(IndicesUtil.MEAN).push("$$ROOT").as("indices"),
Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.INDICES),
new AggregationOperation() {
#Override
public DBObject toDBObject(AggregationOperationContext arg0) {
return new BasicDBObject("$project",
new BasicDBObject("_id",1).append("mean", IndicesUtil.PREFIX+IndicesUtil.MEAN).append("firstResult",
new BasicDBObject("$multiply",multiplyDBList)));
}
},
Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),
new AggregationOperation() {
#Override
public DBObject toDBObject(AggregationOperationContext arg0) {
return new BasicDBObject("$project",
new BasicDBObject(IndicesUtil.DATA,
new BasicDBObject("$sqrt","$secondResult").append("mean", IndicesUtil.PREFIX+IndicesUtil.MEAN)));
}
}
);
I am getting problem with bellow line
Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),
And error as per bellow
Invalid reference '$firstResult'!
Thanks in advance.
You can simplify your aggregation on 1.10.1-Release spring mongo version. You should avoid using BasicDBObject/Document and use spring provided helper methods.
Aggregation meanAggregation = Aggregation.newAggregation(
Aggregation.match(Criteria.where(IndicesUtil.INDICES_ID).is(indicesId)),
Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.DATA_SETS),
Aggregation.match(Criteria.where(IndicesUtil.DATA_SETS_DATE).gte(startDate).lte(indicesDataSet.getDate())),
Aggregation.group(IndicesUtil.INDICES_ID).avg(averageParameter).as(IndicesUtil.MEAN).push("$$ROOT").as("indices"),
Aggregation.unwind(IndicesUtil.PREFIX+IndicesUtil.INDICES),
Aggregation.project("_id", "mean").andExpression("(indices.dataSets.data - mean) * (indices.dataSets.data - mean)").as("firstResult"),
Aggregation.group().avg("$firstResult").as("secondResult").first(IndicesUtil.PREFIX+IndicesUtil.MEAN).as(IndicesUtil.MEAN),
Aggregation.project("mean").and("secondResult").sqrt().as(IndicesUtil.DATA)
);

How to add document in existing nested documents dynamically in mongodb

i have following structure
{
"name": "abc",
"lname": "xyz",
"data": {
"1": {
"info": {
"test": "test"
},
"info1": {
"test": "test"
}
}
}
}
now i want to add following object in 'data' object
"2": {
"info": {
"test": "test1"
},
"info1": {
"test": "test1"
}
}
how to do that in mongodb using mongodb java driver?
In MongoDB shell you can do it as below :
db.collection.update( {_id:id} , { $set: { "data.2":
{
"info": {"test": "test1" }, "info1": {"test": "test1"}
}
}});
In Java driver :
DBObject query = new BasicDBObject("_id", "123");
DBObject update = new BasicDBObject();
DBObject info = new BasicDBObject("test","test1");
update.put("$set", new BasicDBObject("data.2",
new BasicDBObject("info",info).append("info1",info));
collection.update(query, update);

Categories