Accessing data from mongodb

Gibbs :

I have the following types of requests.

server/controllerName/access_id/id/field/field_value/api_name
server/controllerName/access_id/id/field/field_value/field2/field_value/api_name

Few field examples:

1. start date and end date
2. user name
3. user group

Mongo DB data format:

Mongo DB stores user order details. Each order contains user detail[10 fields] and order details[30 fields]

API has to give by default last 30 days of orders if no date is mentioned.

My question:

How can I efficiently read this data from mongo db?

What I am currently doing:

I am parsing the httprequest and adding these fields to a map

{"name":"gibbs", "category":"vip"}

I have to get all the documents where these two fields are matching and return the documents in the following form.

{
 user: "gibbs",
 total_Result: 10,
 [
  {
   //order details items from doc 1
  }
  {
   //order details from doc2
  }
 ]
 }

I am querying mongo db as follows.

MongoCollection<Document> mongoEngCollection = mongoDbReader.getCollection();
        BasicDBObject andQuery = new BasicDBObject();
        List<BasicDBObject> obj = new ArrayList<BasicDBObject>();

        //Forming query using request parameter. requestAttributes contains map of request parameters.
        for(Map.Entry<PathAttribute, PathValue<?>> entry : requestAttributes.entrySet()) {
            String key = entry.getKey().getName();
            obj.add(new BasicDBObject(key, entry.getValue().getRawValue()));
        }

        andQuery.put("$and", obj);

        //Queryng mongo db
        FindIterable<Document> documents = mongoEngCollection.find(andQuery);

Then I am iterating the documents and grouping the fields as the required format.

It is written using spring.

I am fine with schema changes, query changes, annotation methods as long as it is very fast and conceptually correct.

Please advise me.

user2683814 :

You've to use aggregation framework. Statically import all the methods of helper classes and use the below code.

Use of BasicDBObject is deprecated in newer 3.x driver api. You should use the new class Document for similar needs.

import static com.mongodb.client.model.Accumulators.*;
import static com.mongodb.client.model.Aggregates.*;
import static java.util.Arrays.asList;
import static com.mongodb.client.model.Filters.*;
import static com.mongodb.client.model.Projections.*;
import org.bson.conversions.Bson;

MongoCollection<Document> mongoEngCollection = mongoDbReader.getCollection();

List<Bson> obj = new ArrayList<>();
//Forming query using request parameter. requestAttributes contains map of request parameters.
for(Map.Entry<PathAttribute, PathValue<?>> entry : requestAttributes.entrySet()) {
   String key = entry.getKey().getName();
   //Check if key is not date and set the start and end date
   obj.add(eq(key, entry.getValue().getRawValue()));
}

//Build aggregation stages
Bson match = match(and(obj));
Bson group = group(
              first("user", "$name"), 
              sum("total_results", 1), 
              push("results", "$$ROOT")
);
Bson projection = project(fields(excludeId()));

//Query Mongodb
List<Document> results = mongoEngCollection .aggregate(asList(match, group, projection)).into(new ArrayList<Document>());

More about aggregation here https://docs.mongodb.com/manual/reference/operator/aggregation/

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=121013&siteId=1