0

我从客户那里得到一个字符串。此字符串可以匹配我的组中的一个字符串,或者一个底层项目的字符串之一。此字符串是必须查询。

我得到了嵌套查询容器和普通查询容器的多重匹配。我的问题是:如何在单个多重匹配中同时获得嵌套层和顶层?

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 个单个查询。因此,在“必须”级别上,它们不会相互抵消。(如果字符串与组匹配但不匹配他的基础项目之一,则两者都不会显示)。

4

1 回答 1

1

使用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)
                )
            )
        )
    )
);
于 2018-06-13T00:05:41.953 回答