Mongodb java驱动程序性能缓慢

时间:2017-10-06 05:45:12

标签: java mongodb tomcat servlets

我正在开发一个前端实现的项目:VUE.JS和后面:Java servlet(tomcat)。我的servlet在具有数千种产品的mongoDB数据库上执行请求。 (我是mongodb查询的新手)。

对我来说问题是我的servlet花了很多时间来回应数据数组。

我需要建议来加快查询速度并加快我的servlet进程向前发送数据。

  1. 首先我想知道在mongodb中,使用这样的查询是否有效(这是一个带有很多查询的查询示例,因为我必须从许多集合中获取数据):

    db.getCollection('collection_name').aggregate([
       {
          "$match":{
             "_id": ObjectId("xxxxxxxxxxxxxxxxx")
          }
       },
       {
          "$lookup":{
             "from":"collection_name",
             "localField":"id",
             "foreignField":"id",
             "as":"trans"
          }
       },
       {
          "$unwind":"$trans"
       },
       {
          "$lookup":{
             "from":"collection_name",
             "localField":"trans.id",
             "foreignField":"trans_id",
             "as":"orders"
          }
       },
       {
          "$unwind":"$orders"
       },
       {
          "$match":{
             "$and":[
                {
                   "orders.status":"status_state"
                }
             ]
          }
       },
       {
          "$unwind":"$orders.products"
       },
       {
          "$lookup":{
             "from":"collection_name",
             "localField":"orders.products.id",
             "foreignField":"id",
             "as":"detailsProducts"
          }
       },
       {
          "$unwind":"$detailsProducts"
       },
       {
          "$unwind":"$detailsProducts.products"
       },
       {
          "$project":{
             "_id":1,
             "orders":1,
             "detailsProducts": 1
          }
       }
    ])
    
  2. 第二,正如我所说,我的java servlet需要很多时间来执行数据处理,在对我的聚合进行处理后,我执行循环操作将数据推送到json数组中,如下所示:

    // Define json array
    JSONArray array = new JSONArray();
    
    // Get collection
    AggregateIterable<Document> myCollection = 
        MongoDB.getCollection("coll_name").aggregate(...);
    
    // Going through all documents (thousands of document)
    for (Document orderDocument : orderCollection) {
      // Get all products and they references
      arrays.put(new JSONObject(orderDocument.toJson()));
    }
    
    // AFTER THE END OF LOOP, MY SERVLET SEND THE ARRAY TO THE FRONT
    
  3. 注意:我使用mongodb java驱动程序3.5(我同时尝试:核心驱动程序和异步驱动器)

    我想得到一些建议,加快治疗速度并优化我的要求。

1 个答案:

答案 0 :(得分:0)

构建具有数千个元素的JSONArray并不会很好地扩展。您最好直接将JSON流式传输回客户端。所以,假设这在合理的时间内返回:

// Get collection
AggregateIterable<Document> myCollection =
    MongoDB.getCollection("coll_name").aggregate(...);

然后像下面这样的东西应该大大改善:

import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.bson.Document;
import org.bson.codecs.DocumentCodec;
import org.bson.codecs.Encoder;
import org.bson.codecs.EncoderContext;
import org.bson.json.JsonWriter;
...
public void writeAsJsonTo(AggregateIterable<Document> orderCollection,
        HttpServletResponse httpServletResponse) throws IOException {
    final Encoder<Document> encoder = new DocumentCodec();
    final JsonWriter jsonWriter =
        new JsonWriter(httpServletResponse.getWriter());
    final EncoderContext encoderContext = EncoderContext.builder()
        .isEncodingCollectibleDocument(true).build();

    jsonWriter.writeStartDocument();
    jsonWriter.writeStartArray("orders");
    // Going through all documents (thousands of document)
    for (Document orderDocument : orderCollection) {
        encoder.encode(jsonWriter, orderDocument, encoderContext);
    }
    jsonWriter.writeEndArray();
    jsonWriter.writeEndDocument();
}