Фильтрация глубоко вложенного списка с помощью операций агрегирования данных Spring - PullRequest
0 голосов
/ 24 января 2019

У меня есть документ ниже

[ {
        "pageName": "Content_2",
        "domain": "bingo.com",
        "locale": "en-us",
        "contents": [
            {
                "contentName": "Template_2",
                "fields": [
                    {
                        "title": "Company Name"                     
                    },
                    {
                        "title": "Designation"
                    }
                ]
            }
        ]
    },
{
        "version": 2,
        "pageName": "Content_3",
        "domain": "bingo.com",
        "locale": "en-in",
        "contents": [
            {
                "contentName": "Template_2",
                "fields": [
                    {
                        "title": "Company Name"                          
                    },
                    {
                        "title": "Designation"
                    }
                ]
            }
        ]
    }]

Я фильтрую данные на основе домена, локали и contentName. До этого момента все работает нормально. Теперь внутри массива fields я хочу показать только те поля, заголовок которых соответствует определенному значению. Я не могу понять, как это сделать с помощью операции агрегации. Я попробовал ниже фрагмент:

Aggregation aggregation = newAggregation(
                    match(
                        where("domain").is(domain)
                        .and("contents.contentName").is(templateName)
                        .and("locale").in(criteria.getLocales())), 
                        project().and(new AggregationExpression() {
                        @Override
                        public Document toDocument(AggregationOperationContext aggregationOperationContext) {
                            DBObject filterExpression = new BasicDBObject();
                            filterExpression.put("input", "$contents.fields");
                            filterExpression.put("as", "field");
                            filterExpression.put("cond",
                                    new BasicDBObject("$eq", Arrays.<Object>asList("$$field.title", "Company Name")));
                            return new Document("$filter", filterExpression);
                        }

                }).as("field"));
AggregationResults<MyClass> list = mongoOperations.aggregate(aggregation, MyClass.class,
                MyClass.class);

Возвращает все атрибуты как ноль. Пожалуйста, руководство. Я новичок в MongoDB. Спасибо заранее;

1 Ответ

0 голосов
/ 25 января 2019

Вы можете использовать это Агрегирование

db.collection.aggregate([
        { $unwind: '$contents' },
        { $match: { "locale": "en-us", 
"domain": "bingo.com", "contents.contentName": "Template_2"} },
        { $unwind: '$contents.fields' },
        { $match: { 'contents.fields.title' : "Company Name" } },
        { $group: { _id: '$_id', 
              fields: { $push: { title: '$contents.fields.title'}}, 
              "locale" : {$first: "$locale"},
              "domain" : {$first: "$domain"},
              "pageName" : {$first: "$pageName"},
              'contentName': {$first: '$contents.contentName'}
              }
        },
        { $group: { _id: '$_id', 
         "locale" : {$first: "$locale"},
         "domain" : {$first: "$domain"},
         "pageName" : {$first: "$pageName"},
         contents: { $push: { "contentName": '$contentName', "fields": '$fields' }}, 
        }}
    ])

Или просто примените это. Мои извинения Если я ошибся в синтаксисе, но стараюсь изо всех сил, чтобы сделать их правильными

Aggregation aggregation = newAggregation(
                    unwind("contents),
                    match(
                         where("$domain").is(domain)
                        .and("$contents.contentName").is(templateName)
                        .and("$locale").in(criteria.getLocales())
                       ),
                    unwind("$contents.fields"),
                    match(where("$contents.fields.title").is(title)),
                    group("_id")
                     .push("$contents.fields.title").as("fields")
                     .push("$locale").as("locale")
                     .push("$domain").as("domain")
                     .push("$pageName").as("pageName")
                     .push("$contents.contentName").as("contentName"),
                 group("_id")
                 .push("locale").as("locale")
                 .push("domain").as("domain")
                 .push("pageName").as("pageName")
                 .push(new BasicDBObject
                   ("contentName", "$contentName").append
                   ("fields", "$fields").as("contents"))
                );
AggregationResults<MyClass> list = mongoOperations.aggregate(aggregation, MyClass.class,
                MyClass.class);

Run It Ваш результат ждет Вас ...

...