elasticsearch .net客户端复杂查询不工作

lndjwyie  于 2023-05-22  发布在  ElasticSearch
关注(0)|答案(1)|浏览(229)

我有一个名为selected的对象列表,它是这样的形状:List<{bool Selected, String Discriminator, List<int> Tags}>
如果document.VgnItm.Discriminatorselected[index].Discriminator中的一个,并且document.VgnItm.Tags至少有一个来自selected[index].Tags的标记,则选择该文档。
selected只包含一个项目时,此方法有效:

for (var i = 0; i < selected.Count; i++)
{
    QueryContainer &= Query<VgnItmEstSearchDto>.Bool(boolean => boolean.Must(booleanMust =>
            booleanMust.Term(term => term.Field(termField => termField.VgnItm.Discriminator)
                .Value(selected[i].Discriminator)),
               booleanMust => booleanMust.Terms(terms => terms
                .Field(p => p.VgnItm.Tags)
                .Terms(selected[i].Tags)
            ))
    );
}

但是当selected包含两个或更多的项目时,QueryContainer &=意味着document.VgnItm.Discriminator必须是selected[index1].Discriminator,也是selected[index2].Discriminator,这是不可能的。所以它找不到任何结果。
当选定的内容包含多个项目时,我可以在此处执行哪些操作以使此功能正常工作?我不能只使用QueryContainer |=,因为QueryContainer上面还有其他子句。我尝试将Query<VgnItmEstSearchDto>.Bool(boolean => boolean.Must Package 在Bool.Should中,因此它是一个双布尔值,但结果相同。

hjzp0vay

hjzp0vay1#

我能够通过以正确的方式组合QueryContainer来做到这一点。只要我们这样作曲:var compositeQueryContainer = childQueryA.QueryContainer &= childQueryB.QueryContainer,然后有QueryContainer |= Query<VgnItmEstSearchDto>.Bool,就像我在我的问题中提到的,不会否定以前的查询,它会合并它们(与它们而不是或它们)。
因此,我可以按照问题中的方式创建自定义查询,但在循环中使用|=(OR),这会在每个循环周期中构建一个更大的查询容器:

public class ChildQueryB :
    BaseQuery<VgnItmEstSearchDto>
{
    public ChildQueryB(
        string searchTerm,
        List<DiscriminatorTags> selectedDiscriminatorTags = null,
        bool shouldSearchNumberFields = false) :
        base(searchTerm, shouldSearchNumberFields)
    {

        for (var i = 0; i < selectedDiscriminatorTags.Count; i++)
        {
            QueryContainer |= Query<VgnItmEstSearchDto>.Bool(boolean => boolean.Must(booleanMust =>
                    booleanMust.Term(term => term.Field(termField => termField.VgnItm.Discriminator)
                        .Value(selectedDiscriminatorTags[i].Discriminator)),
                       booleanMust => booleanMust.Terms(terms => terms
                        .Field(p => p.VgnItm.Tags)
                        .Terms(selectedDiscriminatorTags[i].Tags)
                    ))
            );
        }
    }
}

然后使用&=将其与父查询中的另一个子查询组合:

public class CompositeQuery :
    BaseQuery<VgnItmEstSearchDto>
{
    public CompositeQuery(
        string searchTerm,
        List<DiscriminatorTags> selectedDiscriminatorTags = null,
        bool shouldSearchNumberFields = false) :
        base(searchTerm, shouldSearchNumberFields)
    {

        
        var childQueryA = new ChildQueryB(searchTerm, true);
        var childQueryB = new ChildQueryA(searchTerm, selectedDiscriminatorTags, true);
        base.QueryContainer = childQueryA.QueryContainer &=
            childQuery.QueryContainer;
    }
}

然后可以像这样使用:

var compositeQuery = new CompositeQuery(searchTerm, discriminatorTags.Where(d => d.Selected == true).ToList(), true);
var results = searchService.Search(compositeQuery, pageNumber, pageSize);

相关问题