MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Các trường được tính toán theo nhóm trong MongoDB

Trước tiên, bạn có thể làm điều gì đó như thế này với "dự án", nhưng đối với tôi thì hơi phản trực giác khi yêu cầu $project giai đoạn trước:

    Aggregation agg = newAggregation(
        project("quantity")
            .andExpression("dayOfMonth(date)").as("day")
            .andExpression("month(date)").as("month")
            .andExpression("year(date)").as("year")
            .andExpression("price * quantity").as("totalAmount"),
        group(fields().and("day").and("month").and("year"))
            .avg("quantity").as("averavgeQuantity")
            .sum("totalAmount").as("totalAmount")
            .count().as("count")
    );

Như tôi đã nói, phản trực quan vì bạn chỉ có thể khai báo tất cả những điều này trong $group nhưng những người trợ giúp dường như không hoạt động theo cách này. Việc tuần tự hóa hơi buồn cười (bao bọc các đối số toán tử ngày bằng các mảng) nhưng nó có vẻ hoạt động. Tuy nhiên, đây là hai giai đoạn chuyển tiếp chứ không phải là một.

Vấn đề với điều này là gì? Bằng cách tách các giai đoạn ra các giai đoạn, phần "dự án" buộc xử lý tất cả các tài liệu trong quy trình để có được các trường được tính toán, điều đó có nghĩa là nó sẽ vượt qua mọi thứ trước khi chuyển sang giai đoạn nhóm.

Có thể thấy rõ sự khác biệt về thời gian xử lý khi chạy các truy vấn ở cả hai hình thức. Với giai đoạn dự án riêng biệt, trên phần cứng của tôi mất thời gian thực thi lâu hơn ba lần so với truy vấn trong đó tất cả các trường được tính toán trong hoạt động "nhóm".

Vì vậy, có vẻ như cách duy nhất hiện nay để xây dựng điều này đúng cách là tự xây dựng đối tượng đường ống:

    ApplicationContext ctx =
            new AnnotationConfigApplicationContext(SpringMongoConfig.class);
    MongoOperations mongoOperation = (MongoOperations) ctx.getBean("mongoTemplate");

    BasicDBList pipeline = new BasicDBList();
    String[] multiplier = { "$price", "$quantity" };

    pipeline.add(
        new BasicDBObject("$group",
            new BasicDBObject("_id",
                new BasicDBObject("month", new BasicDBObject("$month", "$date"))
                    .append("day", new BasicDBObject("$dayOfMonth", "$date"))
                    .append("year", new BasicDBObject("$year", "$date"))
            )
            .append("totalPrice", new BasicDBObject(
                "$sum", new BasicDBObject(
                    "$multiply", multiplier
                )
            ))
            .append("averageQuantity", new BasicDBObject("$avg", "$quantity"))
            .append("count",new BasicDBObject("$sum",1))
        )
    );

    BasicDBObject aggregation = new BasicDBObject("aggregate","collection")
        .append("pipeline",pipeline);

    System.out.println(aggregation);

    CommandResult commandResult = mongoOperation.executeCommand(aggregation);

Hoặc nếu tất cả những điều đó dường như phù hợp với bạn, thì bạn luôn có thể làm việc với nguồn JSON và phân tích cú pháp đó. Nhưng tất nhiên, nó phải là JSON hợp lệ:

    String json = "[" +
        "{ \"$group\": { "+
            "\"_id\": { " +
                "\"month\": { \"$month\": \"$date\" }, " +
                "\"day\": { \"$dayOfMonth\":\"$date\" }, " +
                "\"year\": { \"$year\": \"$date\" } " +
            "}, " +
            "\"totalPrice\": { \"$sum\": { \"$multiply\": [ \"$price\", \"$quantity\" ] } }, " +
            "\"averageQuantity\": { \"$avg\": \"$quantity\" }, " +
            "\"count\": { \"$sum\": 1 } " +
        "}}" +
    "]";

    BasicDBList pipeline = (BasicDBList)com.mongodb.util.JSON.parse(json);


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Nhận _id của một tài liệu được chèn trong MongoDB?

  2. Cách xuất kết quả truy vấn MongoDB sang tệp CSV

  3. Cảnh báo khởi động máy chủ Mongo DB

  4. MongoDB $ log

  5. Tải lên tệp Node.js (Express 4, MongoDB, GridFS, GridFS-Stream)