Как спроектировать карту и уменьшить ее в ProjectionOperation в Spring Data MongoDB? - PullRequest
2 голосов
/ 20 марта 2020

Я не могу выполнить операции map и reduce в java mongodb в ProjectionOperation.

У меня есть операция проекта на нативном mongo query, например:

{
    $project: {
        data: {
            $map: {
                input: params.timeArray,
                in: {
                    "key": "$$this",
                    "value": { "$cond": [{ "$in": ["$$this", "$data.date"] }, "$data", []] }
                }
            }
        }
    }
}

И я также хочу выполнить операцию reduce в другой операции проецирования, например:

{
    $project: {
        id: 1,
        data: { $reduce: { input: "$data", initialValue: [], in: { $concatArrays: ["$$value", "$$this"] } } }
    }
}

Я пробовал это:

ProjectionOperation projectionOperation1 = Aggregation.project()
                .and(VariableOperators.mapItemsOf("data"/*here, I want to pass timeArray*/)
                        .as("input")
                        .andApply(context -> new BasicDBObject("value",
                                ConditionalOperators.when(where("$$this").in("$data.date"))
                                        .then("$data")
                                        .otherwise(new HashSet<>()))))
                .as("data");

Но это не дало мне желаемого результат.

Я использую springboot версию 1.5.10.RELEASE

Любая помощь будет признательна !!

1 Ответ

0 голосов
/ 20 марта 2020

Код операции проецирования выполняется с использованием Spring MongoTemplate API:

MongoOperations mongoOps = new MongoTemplate(MongoClients.create(), "test");

String [] TIME_ARRAY = { "2020-02-20", "2020-02-21", "2020-02-22" }; // values from params.timeArray

Aggregation agg = newAggregation(
  project("_id", "data")
    .andArrayOf(TIME_ARRAY).as("timeArray")
    .andArrayOf().as("emptyArray"),
  project() 
    .and(
        Map.itemsOf("timeArray")
            .as("element")
            .andApply(ctx -> 
                new Document("key", "$$element")
                    .append("value", 
                        new Document("$cond", 
                            Arrays.asList( 
                                new Document("$in", 
                                    Arrays.asList("$$element", "$data.date")), 
                                       "$data", 
                                       "$emptyArray")
                        )
                    ) 
                )
            )
        .as("data")
);

AggregationResults<Document> results = mongoOps.aggregate(agg, "collection", Document.class);

results.forEach(doc -> System.out.println(doc.toJson()));
...