упругое исследование multimatch на вложенных элементах - PullRequest
0 голосов
/ 05 июня 2018

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

Я получил мультиматч, работающий как для вложенных контейнеров запросов, так и для обычных.У меня такой вопрос: как получить как вложенный, так и верхний слой в одном мультиматче?

queryList.Add(q => q
            .MultiMatch(mm => mm
                .Fields(fs => fs
                    .Field(f => f.ExtraText)
                    .Field(f => f.SomeText)
                    .Field(f => f.MoreInfo)
                    .Field(f => f.SEOText)
                    .Field(f => f.Title))
                .Query(filter.SearchString)));
queryList.Add(q => q
            .Nested(c => c
                .Path(p => p.Items)
                .Query(nq => nq
                    .MultiMatch(mm => mm
                        .Fields(fs => fs
                            .Field(f => f.Items.First().Subtitle)
                            .Field(f => f.Items.First().Name)
                            .Field(f => f.Items.First().MoreInfo)
                            .Field(f => f.Items.First().ExtraText)
                            .Field(f => f.Items.First().SEOText))
                        .Query(filter.SearchString)))));

Расширение: Этот поисковый запрос является расширением уже существующих числовых фильтров.Рядом с поиском по тексту есть также фильтр по категориям или из какой страны группа:

if (filter.categories != null && filter.categories.Any())
        {
            foreach (string category in filter.categories)
            {
                queryList.Add(d => d
                    .Nested(nd => nd
                        .Path(np => np.Categories)
                        .Query(nq => nq
                            .Bool(nb => nb
                                .Must(fm => fm
                                    .Match(q => q
                                        .Field(f => f.Categories.First().UrlSlug)
                                        .Query(category)))))));
            }
        }
 if (!string.IsNullOrEmpty(filter.country))
        {
            queryList.Add(d => d.Term(p => p.country, filter.country));
        }

, затем этот список запросов подается на поиск:

 _elasticClient.Search<ProductModel>(d => d
                        .Index(_config.GroupIndexName)
                            .Query(q => q
                                .Bool(b => b.Must(queryList))
                            )
                            .Sort(s => s
                                .Field(f => f
                                    .Field(GetSortField(filter.SortOption))
                                    .Order(filter.SortOrder)
                                )
                            )
                            .Skip((filter.Page - 1) * filter.RecordsPerPage)
                            .Take(filter.RecordsPerPage)
                        );

Что мне нужно, это фильтр для строки поиска, чтобы быть 1 один запрос.Так что на уровне «они должны» они не отменяют друг друга.(если строка соответствует группе, но не одному из его базовых элементов, ни один из них не отображается).

1 Ответ

0 голосов
/ 13 июня 2018

Используйте bool запрос .Похоже, что вы, вероятно, хотите объединить их как should предложения, т.е. соответствовать одному или другому запросу

client.Search<MyDocument>(s => s
    .Query(q => q
        .Bool(b => b
            .Should(sh => sh
                .MultiMatch(mm => mm
                    .Fields(fs => fs
                        .Field(f => f.ExtraText)
                        .Field(f => f.SomeText)
                        .Field(f => f.MoreInfo)
                        .Field(f => f.SEOText)
                        .Field(f => f.Title)
                    )
                    .Query(filter.SearchString)
                ), sh => sh
                .Nested(c => c
                    .Path(p => p.Items)
                    .Query(nq => nq
                        .MultiMatch(mm => mm
                            .Fields(fs => fs
                                .Field(f => f.Items.First().Subtitle)
                                .Field(f => f.Items.First().Name)
                                .Field(f => f.Items.First().MoreInfo)
                                .Field(f => f.Items.First().ExtraText)
                                .Field(f => f.Items.First().SEOText))
                            .Query(filter.SearchString)
                        )
                    )
                )
            )
        )
    )
);

, который может быть выражен более кратко

client.Search<MyDocument>(s => s
    .Query(q => q
        .MultiMatch(mm => mm
            .Fields(fs => fs
                .Field(f => f.ExtraText)
                .Field(f => f.SomeText)
                .Field(f => f.MoreInfo)
                .Field(f => f.SEOText)
                .Field(f => f.Title)
            )
            .Query(filter.SearchString)
        ) || q
        .Nested(c => c
            .Path(p => p.Items)
            .Query(nq => nq
                .MultiMatch(mm => mm
                    .Fields(fs => fs
                        .Field(f => f.Items.First().Subtitle)
                        .Field(f => f.Items.First().Name)
                        .Field(f => f.Items.First().MoreInfo)
                        .Field(f => f.Items.First().ExtraText)
                        .Field(f => f.Items.First().SEOText))
                    .Query(filter.SearchString)
                )
            )
        )
    )
);
...