Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询

这篇具有很好参考价值的文章主要介绍了Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询

概述

ES版本: 7.6.

Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询

需要按照主机ID 进行告警时间的汇总,并且还得把主机相关的信息展示出来。

注: 所有的数据都存在索引中, 通过一个DSL查询展示

实际上就是将terms聚合的结果以列表形式分页展示。

Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询


第一步 : 聚合获取原始数据并分页

GET index_name/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "getAlarmStatistByHostId": {
      "terms": {
        "field": "host_id",
        "size": 100000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "host_details": {
          "top_hits": {
            "size": 1,
            "_source": {
              "include": [
                "host_nameame",
                "host_ip",
                "host_mac"
              ]
            }
          }
        },
        "myBucketSort": {
          "bucket_sort": {
            "from": 0,
            "size": 2,
            "gap_policy": "SKIP"
          }
        }
      }
    },
    "termsCount": {
      "cardinality": {
        "field": "host_id",
        "precision_threshold": 40000
      }
    }
  }
}


知识点:bucket_sort实现分页

  • bucket_sort中 from不是pageNum,如想实现pageNum效果,from=pageNum*size即可;
  • terms聚合的size,实际上size可以尽可能的设置大一点,具体大小按实际情况来看;
"myBucketSort": {
          "bucket_sort": {
            "from": 0,
            "size": 2,
            "gap_policy": "SKIP"
          }
        }

在 bucket_sort 中,可以指定以下其他参数:

  • from: 从哪个桶开始排序,默认是0,表示从第一个桶开始
  • size: 每个桶有多少个桶,默认是2,表示每个桶有2个桶 (其实就是每页展示多少条数据)
  • gap_policy: 桶之间的策略,可选值有:
    • SKIP: 跳过空桶,默认值
    • INTERPOLATE: 使用非空桶的最小和最大值来填充空桶
    • FAIL: 如果遇到空桶,直接失败

所以上述的配置的意思是

  • 从第一个桶开始排序
  • 每个桶有2个子桶
  • 遇到空桶时跳过空桶
    这可以让我们更加精细地控制桶的划分和处理。

知识点:获取 total -----> cardinality 去重

 "termsCount": {
      "cardinality": {
        "field": "host_id",
        "precision_threshold": 40000
      }
    }
  • field: 指定要计算基数的字段,这里是 host_id
  • precision_threshold: 基数的精度 threshold,默认为 40000。高于这个阈值,返回的基数为 estimated 值,低于这个阈值,返回 exact 值。

在 Elasticsearch 中,cardinality 算法用来计算字段的基数(不重复的值的个数).

cardinality 算法是通过 HyperLogLog 算法实现的,所以它很高效,可以支持大规模数据的基数统计,并且精度很高。 缺省值为3000

Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询

精度阈值选项允许用内存交换精度,并定义了一个唯一的计数,在该计数低于此值时,预计计数接近准确。超过这个值,计数可能会变得有点模糊。支持的最大值是40000,高于这个数字的阈值将具有与40000阈值相同的效果。缺省值为3000。

默认情况下,如果基数超过 40000,cardinality 会返回 estimated 值(估算值),否则返回 exact 值(精确值)。如果文档个数远大于40000,那么会返回estimated值,比如50000, 可以通过 precision_threshold 参数控制这个阈值。

所以,cardinality 很适合用于:

  • 统计网站的访问设备/IP 数量
  • 统计不同产品的数量
  • 统计不同用户的数量

它可以提供近实时的统计,对性能影响很小。

小结

利用bucket_sort来分页,cardinality来获取total


第二步 分页并支持模糊查询

方式一 query 方式

GET attack/_search
{
  "size": 0,
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                "match_phrase": {
                  "host_userName": "guo"
                }
              },
              {
                "match_phrase": {
                  "host_ip": "192.168.198.132"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "filter": [
              {
                "terms": {
                  "host_id": [
                    "f261cd4b-8922-4c1f-bb24-72eec4f4245c",
                    "89bd8783-9cbf-4c8d-9160-da4588ee73d7"
                  ]
                }
              }
            ]
          }
        }
      ]
    }
  },
  "aggs": {
    "getAlarmStatistByHostId": {
      "terms": {
        "field": "host_id",
        "size": 100000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "host_details": {
          "top_hits": {
            "size": 1,
            "_source": {
              "include": [
                "host_id",
                "host_userName",
                "host_orgPath",
                "host_ip",
                "host_mac"
              ]
            }
          }
        },
        "myBucketSort": {
          "bucket_sort": {
            "from": 0,
            "size": 2,
            "gap_policy": "SKIP"
          }
        }
      }
    },
    "termsCount": {
      "cardinality": {
        "field": "host_id",
        "precision_threshold": 40000
      }
    }
  }
}


返回

{
  "took" : 19,
  "timed_out" : false,
  "_shards" : {
    "total" : 8,
    "successful" : 8,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "getAlarmStatistByHostId" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "f261cd4b-8922-4c1f-bb24-72eec4f4245c",
          "doc_count" : 10,
          "host_details" : {
            "hits" : {
              "total" : {
                "value" : 10,
                "relation" : "eq"
              },
              "max_score" : 9.781191,
              "hits" : [
                {
                  "_index" : "zfattack-202305",
                  "_type" : "_doc",
                  "_id" : "b19af55c-33ec-4e50-93c2-8ae028d96c5c",
                  "_score" : 9.781191,
                  "_source" : {
                    "host_ip" : "192.168.198.132",
                    "host_mac" : "00-0C-29-CA-E9-4C",
                    "host_orgPath" : """112赣州\ztj单位\ztj部门""",
                    "host_userName" : "guo",
                    "host_id" : "f261cd4b-8922-4c1f-bb24-72eec4f4245c"
                  }
                }
              ]
            }
          }
        }
      ]
    },
    "termsCount" : {
      "value" : 1
    }
  }
}


方式二: 脚本

GET zfattack-*/_search
{
  "size": 0,
  "query": {
    "match_all": {}
  },
  "aggs": {
    "getAlarmStatistByHostId": {
      "terms": {
        "script": {
          "source": "if(doc['host_id'].value.contains('f261cd4b-8922-4c1f-bb24-72eec4f4245c')) {doc['host_id'].value }"
        },
        "size": 100000,
        "order": {
          "_count": "desc"
        }
      },
      "aggs": {
        "host_details": {
          "top_hits": {
            "size": 1,
            "_source": {
              "include": [
                "host_id",
                "host_userName",
                "host_orgPath",
                "host_ip",
                "host_mac"
              ]
            }
          }
        },
        "myBucketSort": {
          "bucket_sort": {
            "from": 0,
            "size": 2,
            "gap_policy": "SKIP"
          }
        }
      }
    },
    "termsCount": {
      "cardinality": {
        "script": {
          "source": "if(doc['host_id'].value.contains('f261cd4b-8922-4c1f-bb24-72eec4f4245c')) {doc['host_id'].value }"
        },
        "precision_threshold": 40000
      }
    }
  }
}

返回

#! Deprecation: Deprecated field [include] used, expected [includes] instead
{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 8,
    "successful" : 8,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "getAlarmStatistByHostId" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "f261cd4b-8922-4c1f-bb24-72eec4f4245c",
          "doc_count" : 10,
          "host_details" : {
            "hits" : {
              "total" : {
                "value" : 10,
                "relation" : "eq"
              },
              "max_score" : 1.0,
              "hits" : [
                {
                  "_index" : "zfattack-202305",
                  "_type" : "_doc",
                  "_id" : "7b761eaa-8b65-4608-b3d9-89a82c9b1784",
                  "_score" : 1.0,
                  "_source" : {
                    "host_ip" : "192.168.198.132",
                    "host_mac" : "00-0C-29-CA-E9-4C",
                    "host_orgPath" : """112赣州\ztj单位\ztj部门""",
                    "host_userName" : "guo",
                    "host_id" : "f261cd4b-8922-4c1f-bb24-72eec4f4245c"
                  }
                }
              ]
            }
          }
        }
      ]
    },
    "termsCount" : {
      "value" : 1
    }
  }
}

cardinality 的 script

可以通过 cardinality 的 script 参数来达到过滤的效果。
语法是:

"cardinality": {
  "field": "field_name",
  "script": "condition" 
}

这会统计 field_name 字段中满足 script 条件的基数。
例如,有文档:

{ "age": 10 } 
{ "age": 20 }
{ "age": 30 }
{ "age": 40 }

如果我们要统计 age > 30 的基数,可以使用:

"cardinality": {
  "field": "age",
  "script": "doc['age'].value > 30" 
}

这会返回 2,因为只有 age = 40 的文档满足条件。
再比如,要统计同时满足 age > 30 和 gender = “male” 的用户基数,可以使用:

"cardinality": {
  "field": "age",  
  "script": "doc['age'].value > 30 && doc['gender'].value == 'male'" 
}

这里的 script 使用 Elasticsearch 的 Painless 脚本语言,可以非常灵活地设置过滤逻辑。
所以,通过 script 参数,我们可以实现一些过滤条件,然后统计满足这些条件的字段基数,这给我们带来很大灵活性。

除了 cardinality 聚合,在 termsCount 查询中也可以使用 script 过滤:

"termsCount": {
  "cardinality": {
    "field": "age",
    "script": "doc['age'].value > 30" 
  }
}

这会返回一个 filtered 基数,代表 age 大于 30 的值有多少个。
所以 script 参数让 cardinality 和 termsCount 变得更加强大和灵活。

Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询文章来源地址https://www.toymoban.com/news/detail-448292.html

到了这里,关于Elasticsearch - 聚合获取原始数据并分页&排序&模糊查询的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SpringBoot ElasticSearch 聚合排序

    Spring Boot和Elasticsearch的集成主要涉及使用Spring Data Elasticsearch库。Elasticsearch是一个分布式搜索引擎,它提供了丰富的RESTful API,用于索引、搜索和分析大量数据。 在Spring Boot中,你可以使用Spring Data Elasticsearch来简化与Elasticsearch的交互。Spring Data Elasticsearch提供了对Elasticsearch的

    2024年01月23日
    浏览(37)
  • Springboot操作Elasticsearch——聚合分组与排序

    这两天项目中需要从es中查询数据,根据某个字段进行分组,求其最大、最小、平均值,并按最大值进行排序。 springboot的版本号:2.0.6.RELEASE Elasticsearch的版本号:5.6.3 主要代码记录下: BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()                 .filter(QueryBuilders.termsQu

    2024年02月16日
    浏览(33)
  • Elasticsearch:RestHighLevelClient实现搜索、分页、排序、高亮

    1.引入依赖 2.自定义搜索DTO 3.封装工具类、实现 分页、高亮、排序 反射工具类 ReflectUtil 是我自定义的,原理是反射,可以引入hutool的工具包,同样也可以实现该结果

    2024年02月11日
    浏览(32)
  • 【ElasticSearch】JavaRestClient实现文档查询、排序、分页、高亮

    先初始化JavaRestClient对象: 代码和DSL对应上就是: 运行结果: 然后是对结果的解析,对照响应结果: 示例代码: 运行结果: 总结: 构建DSL是通过HighLevelRestClient中的resource()方法来实现的,这里包含了查询、排序、分页、高亮等操作 构建查询条件的核心部分,即查询类型,

    2024年02月14日
    浏览(37)
  • 解决Elasticsearch的Text类型的字段参与聚合和排序

    text字段类型用于全文内容,例如电子邮件正文或产品说明,并且es会通过分析器对字符串进行分词,可以在全文检索中搜索单独的单词。文本字段最适合非结构化但可读的内容并且不用于排序,也很少用于聚合 keyword主要用于结构化内容的字段,并且总是会有相同值的字段。

    2024年02月11日
    浏览(34)
  • Elasticsearch聚合学习之四:结果排序,阿里云java面试

    返回结果如下,已经按照key的大小从大到小排序: … “aggregations” : { “price” : { “buckets” : [ { “key” : 80000.0, “doc_count” : 1 }, { “key” : 60000.0, “doc_count” : 0 }, { “key” : 40000.0, “doc_count” : 0 }, { “key” : 20000.0, “doc_count” : 4 }, { “key” : 0.0, “doc_count” : 3 } ] } } }

    2024年04月09日
    浏览(30)
  • spring boot使用elasticsearch分词,排序,分页,高亮简单示例

    记,写一个简单的es分词demo,es版本6.8.12 如果使用es7有些方法可能会有所改变,请参考7的文档 es安装教程:http://t.csdn.cn/BSh12 怎么简单怎么来 商品名称加了 @Field(type = FieldType.Text, analyzer = “ik_max_word”) 会自动分词 分页处理 3.2.1 分词 当输入衣服鞋子的时候会将分

    2024年02月08日
    浏览(27)
  • SpringBoot 整合ElasticSearch实现模糊查询,批量CRUD,排序,分页,高亮

    准备一个空的SpringBoot项目 写入依赖 注意你的SpringBoot和你的es版本,一定要对应,如果不知道的可以查看这篇文章:https://blog.csdn.net/u014641168/article/details/130386872 我的版本是2.2.6,所以用的ES版本是 6.8.12,安装es请看这篇文章:https://blog.csdn.net/u014641168/article/details/130622430 查看

    2024年02月08日
    浏览(41)
  • Spring Boot Elasticsearch7.6.2实现创建索引、删除索引、判断索引是否存在、获取/添加/删除/更新索引别名、单条/批量插入、单条/批量更新、删除数据、递归统计ES聚合的数据

    注意:我的版本是elasticsearch7.6.2、spring-boot-starter-data-elasticsearch-2.5.6 引入依赖 有时候你可能需要查询大批量的数据,建议加上下面配置文件

    2024年02月13日
    浏览(51)
  • ElasticSearch - 基于 JavaRestClient 查询文档(match、精确、复合查询,以及排序、分页、高亮)

    目录 一、基于 JavaRestClient 查询文档 1.1、查询 API 演示 1.1.1、查询基本框架 DSL 请求的对应格式 响应的解析 1.1.2、全文检索查询 1.1.3、精确查询 1.1.4、复合查询 1.1.5、排序和分页 1.1.6、高亮 1.1.1、查询基本框架 接下里通过一个 match_all 查询所有,来演示以下基本的 API. 由上可

    2024年02月07日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包