Агрегация Spring Data MongoDB возвращает пустые данные, но работает на Compass с тем же конвейером

#java #spring #mongodb #spring-mvc #spring-data-mongodb

#java #spring #mongodb #spring-mvc #spring-data-mongodb

Вопрос:

У меня возникла проблема с запросом данных MongoDB. Вот этот документ:

 {
   productId:1,
   warehouses:[
             warehouseId:1,
             productBatch:[
                          {
                            unitPrice:15.5,
                            quantity:1000,
                            expireSearchTimestamp:14145555545,
                            currentQuantity:50
                          },{
                            unitPrice:17.5,
                            quantity:1000,
                            expireSearchTimestamp:14145555545,
                            currentQuantity:50
                          }
               ]
          ]
}
 

и по коду это

 public List<ProductSearchResult> findCustomSearch(List<Integer> medicines,
            List<Integer> warehousesIds, int quantity)
    {
        UnwindOperation unwind1 = Aggregation.unwind("warehouses");
        UnwindOperation unwind2 = Aggregation.unwind("warehouses.productBatch");
        ProjectionOperation project = Aggregation.project("warehouses.productBatch");
        MatchOperation match = Aggregation.match(Criteria.where("productId").in(productIds)
                .and("warehouses.warehouseId").in(warehousesIds)
                .and("warehouses.productBatch.currentQuantity").gte(quantity));
        SortOperation sort = Aggregation.sort(Direction.ASC, "productBatch.unitPrice");
        LimitOperation limit = Aggregation.limit(3);
        Aggregation aggregation = Aggregation
                .newAggregation(unwind1, unwind2, project, sort, limit)
                .withOptions(Aggregation.newAggregationOptions().allowDiskUse(true).explain(true)
                        .cursor(new BasicDBObject()).build());
            AggregationResults<ProductSearchResult> results = mongoTemplate.aggregate(aggregation,
                    "medicine", ProductSearchResult.class);
            List<ProductSearchResult> mappedResults = results.getMappedResults();
            return mappedResults;
        }
 

это вывод функции

 [
    {
        "$unwind": "$warehouses"
    },
    {
        "$unwind": "$warehouses.productBatch"
    },
    {
        "$match": {
            "productId": {
                "$in": [
                    20,
                    21
                ]
            },
            "warehouses.warehouse_id": {
                "$in": [
                    1,
                    2,
                    3,
                    4,
                    5
                ]
            },
            "warehouses.productBatch.currentQuantity": {
                "$gte": 10
            }
        }
    },
    {
        "$project": {
            "medicine_search": "$warehouses.productBatch"
        }
    },
    {
        "$sort": {
            "productBatch.unitPrice": 1
        }
    },
    {
        "$limit": 3
    }
]
 

когда я запускаю эту функцию, я получаю пустой список, но, согласно mongo compass, я получил 3 элемента.

Спасибо

Комментарии:

1. .explain(true) — для чего нужна эта опция?

2. согласно документации, это ссылка для информации «debug»

3. Вы использовали explain в Compass ( «… но, согласно mongo compass, я получил 3 элемента » )?

4. Нет ,, но я удалил его, но никаких изменений не произошло

5. Я редактирую сообщение с помощью конвейера агрегации, когда я его распечатываю, вы можете это проверить

Ответ №1:

Я не знаю, почему этот блок кода не работает, но следующий меня устраивает

 public void finalTry(List<Integer> productIds,
            List<Integer> warehousesIds, int q, int limitN)
    {
        DBCollection collection = mongoTemplate.getCollection("product");
        DBObject limit = new BasicDBObject("$limit", limitN);
        DBObject sort = new BasicDBObject("$sort",
                new BasicDBObject("productBatch.unitPrice", 1));
        DBObject unwind1 = new BasicDBObject("$unwind", "$warehouses");
        DBObject unwind2 = new BasicDBObject("$unwind", "$warehouses.productBatch");
        DBObject project = new BasicDBObject("$project",
                new BasicDBObject("productBatch", "$warehouses.productBatch"));
        DBObject match1 = new BasicDBObject("$match",
                new BasicDBObject("productId", new BasicDBObject("$in", productIds)));
        DBObject match2 = new BasicDBObject("$match", new BasicDBObject("warehouses.warehouseId",
                new BasicDBObject("$in", warehousesIds)));
        DBObject match3 = new BasicDBObject("$match", new BasicDBObject(
                "warehouses.productBatch.currentQuantity", new BasicDBObject("$gte", q)));

        List<DBObject> pipeline = Arrays.asList(match1, unwind1, match2, unwind2, match3, project,
                sort, limit);
        AggregationOutput output = collection.aggregate(pipeline);
        for (DBObject d : output.results())
        {
            System.out.println(d)
        }
    }
 

Спасибо