Elasticsearch嵌套添加多个范围查询

twh00eeo  于 2023-04-11  发布在  ElasticSearch
关注(0)|答案(2)|浏览(216)

我有一个dynamic搜索描述符生成器。其中一个步骤是遍历范围过滤器列表并将其添加到搜索描述符中。但是,我添加的任何范围查询都会覆盖以前的范围查询。如何将范围查询追加到已添加的范围查询列表中

public SearchDescriptor<dynamic> FilterSearch(SearchDescriptor<dynamic> searchDescriptor, List<FilterField> filters)
{
    foreach (var filter in filters)
    {
        searchDescriptor = AddFilterToSearch(searchDescriptor, filter);
    }

    return searchDescriptor;
}

private static SearchDescriptor<dynamic> AddFilterToSearch(SearchDescriptor<dynamic> searchDescriptor, FilterField filter)
{
    var range = new RangeQuery
    {
        Field = filter.Field
    };
    var term = new TermQuery
    {
        Field = filter.Field
    };

    string rangeValue = filter.Value == null ? null : JsonConvert.ToString(filter.Value);

        // trim the quotes that JsonConvert wraps around the value for some reason
    if (rangeValue != null && rangeValue.StartsWith("\"") && rangeValue.EndsWith("\""))
        rangeValue = rangeValue.Substring(1, rangeValue.Length - 2);

    switch (filter.Operator)
    {
        case Enums.ComparrisonOperator.LowerThan:
            range.LowerThan = rangeValue;
            break;
        case Enums.ComparrisonOperator.LowerThanOrEqualTo:
            range.LowerThanOrEqualTo = rangeValue;
            break;
        case Enums.ComparrisonOperator.Equals:
            if (filter.Value != null && filter.Value is string)
                filter.Value = filter.Value.ToString().ToLowerInvariant();
            term.Value = filter.Value;
            break;
        case Enums.ComparrisonOperator.GreaterThan:
            range.GreaterThan = rangeValue;
            break;
        case Enums.ComparrisonOperator.GreaterThanOrEqualTo:
            range.GreaterThanOrEqualTo = rangeValue;
            break;
    }

    switch (filter.Operator)
    {
        case Enums.ComparrisonOperator.LowerThan:
        case Enums.ComparrisonOperator.LowerThanOrEqualTo:
        case Enums.ComparrisonOperator.GreaterThan:
        case Enums.ComparrisonOperator.GreaterThanOrEqualTo:
            searchDescriptor = searchDescriptor.Query(range);
            break;
        case Enums.ComparrisonOperator.Equals:
            searchDescriptor = searchDescriptor.Query(term);
            break;
    }

    return searchDescriptor;
}
zvms9eto

zvms9eto1#

如果你正在使用NEST,我认为你应该使用QueryContainer。

var result = _Instance.Search<Record>(s => s
              .Index("indexName")
              .Type("type")
              .Query(q =>
              {
                QueryContainer query = null;
                QueryContainer filter1 = null;
                QueryContainer filter2 = null;
                QueryContainer filter3 = null;

                query = q.QueryString(qs=>qs.OnFields(f => f.RecordValue).Query(term));

                filter1 = q.Filter(ff => ff.Range(n => n.OnField(f => f.minAge).Lower(20));
                filter2 = q.Filter(ff => ff.Range(n => n.OnField(f => f.minAge).Greater(20)); 
                filter3 = q.Filter(ff => ff.Range(n => n.OnField(f => f.maxAge).Lower(60));                   

                //You can put some conditions in here so you will
                switch (filter.Operator)
                {
                    case Enums.ComparrisonOperator.LowerThan:
                        return query && filter1;
                        break;
                    case Enums.ComparrisonOperator.GreaterThan:
                        return query && filter2;
                        break;
                }
              })
              .Take(10)
              );

或者类似的东西....希望它能有所帮助!当然...这是针对Elasticsearch〈2.0的

5w9g7ksd

5w9g7ksd2#

您可以使用QueryContainer添加它,如下所示

var queryContainers = new List<QueryContainer>();            
        var descriptor = new QueryContainerDescriptor<ProcedureServiceRequest>();
        queryContainers.Add(descriptor.DateRange(r => r.Field(f => f.Patient.Birthdate).GreaterThanOrEquals(startDate).LessThanOrEquals(endDate)));            
        var queryContainer = new QueryContainerDescriptor<ProcedureServiceRequest>().Match(m => m.Field(f => f.Specialty).Query("Ortho1"));
        queryContainers.Add(queryContainer);
        var queryContainer2 = new QueryContainerDescriptor<ProcedureServiceRequest>().Match(m => m.Field(f => f.PerformingPhysician.Id).Query("Practitioner2"));            
        queryContainers.Add(queryContainer2);

        var filterQuery = new BoolQuery
        {
            Filter = queryContainers
        };

        
        var searchResponse = await elasticClient.SearchAsync<ProcedureServiceRequest>(s => s // Define the search query
                                .Index(indexName).Take(10000)
                                .Query(q => q
                                 .Bool(b => b
                                    .Filter(filterQuery

                                    )
                                    .Must(m => m
                                .QueryString(qs => qs
                                
                                .Fields(fs => fs.Field("*"))
                                .Query(query))))).Sort(srt => srt.Field(f=> {
                                    f.Order(Nest.SortOrder.Ascending);

                                    switch (sortfield)
                                    {
                                        case "Birthdate":
                                            f.Field(ff => ff.Patient.Birthdate);
                                            break;
                                       
                                        default:
                                            f.Field(ff => ff.Start);
                                            f.Descending();
                                            break;
                                    }

                                    return f;
                                })));          
        

        return searchResponse.Documents.ToList();

相关问题