如何使用嵌套生成筛选器聚合?

wnrlj8wa  于 2021-06-13  发布在  ElasticSearch
关注(0)|答案(1)|浏览(572)

我需要使用nest过滤聚合。但由于我不太了解这一点,因此,我提出以下建议

class Program
{
        static void Main(string[] args)
        {

            ISearchResponse<TestReportModel> searchResponse =
                            ConnectionToES.EsClient()
                            .Search<TestReportModel>
                            (s => s
                                .Index("feedbackdata")
                                .From(0)
                                .Size(50000)
                                .Query(q =>q.MatchAll())
                            );

            var testRecords = searchResponse.Documents.ToList<TestReportModel>();

            result = ComputeTrailGap(testRecords);

        }

        private static List<TestModel> ComputeTrailGap(List<TestReportModel> testRecords)
        {
            var objTestModel = new List<TestModel>();          

            var ptpDispositionCodes = new string[] { "PTP" };
            var bptpDispositionCodes = new string[] { "BPTP","SBPTP" };

            int gapResult = testRecords.Where(w => w.trailstatus == "Gap").Count();           

            var ptpResult = testRecords.Where(w => ptpDispositionCodes.Contains(w.lastdispositioncode)).ToList().Count();

            var bptpResult = testRecords.Where(w => bptpDispositionCodes.Contains(w.lastdispositioncode)).ToList().Count();

            objTestModel.Add(new TestModel { TrailStatus = "Gap", NoOfAccounts = gapResult });           
            objTestModel.Add(new TestModel { TrailStatus = "PTP", NoOfAccounts = ptpResult });
            objTestModel.Add(new TestModel { TrailStatus = "BPTP", NoOfAccounts = bptpResult });         

            return objTestModel;
        }
}

dto公司

public class TestReportModel
{

    public string trailstatus { get; set; }        
    public string lastdispositioncode { get; set; }        
}

public class TestOutputAPIModel
{
    public List<TestModel> TestModelDetail { get; set; }    
}

public class TestModel
{   
    public string TrailStatus { get; set; }
    public int NoOfAccounts { get; set; }

}

这个程序可以工作,但我们可以发现,我们只是通过nest访问ElasticSearch,其余的聚合/过滤都是使用lambda完成的。
我想使用nest框架执行整个操作(聚合/过滤等),并使用过滤聚合将其放入testmodel中
如何在嵌套中构造dsl查询?
更新
到目前为止,我已经能够进行以下操作,但计数为零。我的查询构造有什么问题

var ptpDispositionCodes = new TermsQuery
            {
                IsVerbatim = true,
                Field = "lastdispositioncode",
                Terms = new string[] { "PTP" },
            };
var bptpDispositionCodes = new TermsQuery
{
    IsVerbatim = true,
    Field = "lastdispositioncode",
    Terms = new string[] { "BPTP" },
};

 ISearchResponse<TestReportModel> searchResponse =
                ConnectionToES.EsClient()
                .Search<TestReportModel>
                (s => s
                    .Index("feedbackdata")
                    .From(0)
                    .Size(50000)
                    .Query(q =>q.MatchAll())
                    .Aggregations(fa => fa

                        .Filter("ptp_aggs", f => f.Filter(fd => ptpDispositionCodes))
                        .Filter("bptp_aggs", f => f.Filter(fd => bptpDispositionCodes))

                        )
               );

结果


非常感谢。

iqih9akk

iqih9akk1#

我看到您正在尝试对 TestReportModel . 你的方法的整体结构似乎已经足够好了。但是,附加到筛选器容器的查询有问题。
你的 TestReportModel 包含两个属性 trialStatus 以及 lastdispositioncode . 您正在设置 Field 属性的描述 terms 查询。这就是为什么你认为计数为零。对其执行搜索的模型(反过来,对其执行搜索的索引)没有属性 description 这就是区别。 NEST 或者elasticsearch,在这种情况下不会引发任何异常。相反,它返回count zero。 Field 值应修改为 lastdispositioncode .

// Type on which the search is being performed. 
// Response is of the type ISearchResponse<TestReportModel>
public class TestReportModel
{
    public string trailstatus { get; set; }        
    public string lastdispositioncode { get; set; }        
}

被改进的 terms 查询如下

// Field is "lastdispositioncode" and not "description"
// You may amend the Terms field as applicable
var ptpDispositionCodes = new TermsQuery
{
    IsVerbatim = true,
    Field = "lastdispositioncode",
    Terms = new string[] { "PTP" },
};

var bptpDispositionCodes = new TermsQuery
{
    IsVerbatim = true,
    Field = "lastdispositioncode",
    Terms = new string[] { "BPTP", "SBPTP" },
};

因为看起来 lastdispositioncode 似乎只取一个单词值(示例中的ptp或bptp),我相信,是否分析文档中的字段无关紧要。您还可以从 ISearchResponse<T> 类型如下所示

var ptpDocCount = ((Nest.SingleBucketAggregate)response.Aggregations["ptp_aggs"]).DocCount;
var bptpDocCount = ((Nest.SingleBucketAggregate)response.Aggregations["bptp_aggs"]).DocCount;

编辑:添加关键字搜索方法

QueryContainer qc1 = new QueryContainerDescriptor<TestReportModel>()
    .Bool(b => b.Must(m => m.Terms(t => t.Field(f => f.lastdispositioncode.Suffix("keyword"))
        .Terms(new string[]{"ptp"}))));

QueryContainer qc2 = new QueryContainerDescriptor<TestReportModel>()
    .Bool(b => b.Must(m => m.Terms(t => t.Field(f => f.lastdispositioncode.Suffix("keyword"))
        .Terms(new string[]{"bptp", "sbptp"}))));

现在,这些查询容器可以连接到聚合,如下所示

.Aggregations(aggs => aggs
    .Filter("f1", f => f.Filter(f => qc1))
    .Filter("f2", f => f.Filter(f => qc2)))

对由生成的聚合的查询 NEST 本例中的客户端如下所示

"f1": {
      "filter": {
        "bool": {
          "must": [
            {
              "terms": {
                "lastdispositioncode.keyword": [
                  "bptp"
                ]
              }
            }
          ]
        }
      }
    }

另外,回到搜索不区分大小写的情况,elasticsearch以不区分大小写的方式处理搜索。但是,它因分析字段与未分析字段的不同而不同。分析的字段被标记化,文本字段默认被标记化。我们使用 suffix 可拓方法 NEST 对分析场进行理想匹配,得到分析场的精确匹配。更多关于他们的信息

相关问题