• es 未分词字段搜索过程


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 浮世★繁華 2024-04-20 18:36 采纳率: 12.5% 浏览 1 首页/ 大数据 / es 未分词字段搜索过程 elasticsearch搜索引擎全文检索 我想问一下es搜索分词字段是根据倒排索引搜索的,如果搜索未分词字段,或者数值等其他非文本字段,这个没有倒排索引,搜索的时候是全表扫描还是有什么优化措施呢 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    4条回答 默认 最新

    • 专家-赤兔[在线] 全栈领域优质创作者 2024-04-20 18:36
      关注

      引自免费微信小程序:皆我百晓生

      在Elasticsearch中,对于未分词字段(比如数值、日期或其他类型的数据)的搜索,它并不会进行全文本分析,而是使用特定的数据结构进行查询,这通常被称为“位图过滤器”(Bitmap Filters)。这些数据结构使得Elasticsearch可以高效地处理范围查询、精确匹配以及布尔逻辑组合。

      当对非文本字段执行搜索时,Elasticsearch不会进行倒排索引的查找,而是使用以下方法之一:

      1. Term Query:如果你正在寻找一个精确匹配的值,Elasticsearch会使用term query。它会在内部数据结构中查找指定的值,而不是遍历整个文档。对于数值和日期类型的字段,这通常意味着快速查找,因为它们已经排序并存储为二进制格式。

        from elasticsearch import Elasticsearch
        
        es = Elasticsearch()
        query = {
            "query": {
                "term": {"your_field_name": "your_value"}
            }
        }
        
        response = es.search(index="your_index", body=query)
        
      2. Range Query:对于数值或日期范围查询,Elasticsearch会使用位图过滤器,例如range query。它会创建一个表示满足条件的文档集合的位图,从而避免了全表扫描。

        from datetime import datetime, timedelta
        
        es = Elasticsearch()
        
        # 示例范围查询,从当前时间的一周前到当前时间
        start_date = datetime.now() - timedelta(days=7)
        end_date = datetime.now()
        
        query = {
            "query": {
                "range": {
                    "your_date_field": {
                        "gte": start_date.strftime("%Y-%m-%dT%H:%M:%S"),
                        "lte": end_date.strftime("%Y-%m-%dT%H:%M:%S")
                    }
                }
            }
        }
        
        response = es.search(index="your_index", body=query)
        
      3. Script Score Query:如果你需要基于字段的值进行复杂计算,可以使用脚本评分查询(script_score query),但这可能比简单的Term或Range查询更慢。

      4. 聚合查询(Aggregations):对于统计和汇总操作,Elasticsearch提供了强大的聚合功能,可以在不返回具体文档的情况下对数据进行分组和计数。

        from elasticsearch_dsl import Search, A
        
        s = Search(index="your_index").query("match_all")
        s.aggs.bucket("by_your_field", "terms", field="your_field_name")
        
        response = s.execute()
        
        for bucket in response["aggregations"]["by_your_field"]["buckets"]:
            print(bucket["key"], bucket["doc_count"])
        

      综上所述,对于非文本字段的搜索,Elasticsearch利用专门的数据结构和算法来提高效率,避免全表扫描。这样可以确保即使在大规模数据集上也能提供良好的性能。

      展开全部

      评论 编辑记录
    • Kwan的解忧杂货铺 Java领域优质创作者 2024-04-20 18:36
      关注

      晚上好🌙🌙🌙
      本答案参考ChatGPT-3.5

      对于未分词字段或非文本字段,ES搜索的确不能像搜索分词字段一样使用倒排索引进行优化搜索,需要使用其他方式来提高搜索效率。以下是几种实现方案:

      1.使用聚合查询: 可以通过将查询字段作为聚合查询条件,对整个文档进行聚合查询,从而得出符合条件的文档。但是,这种方式不适用于排序等需要基于查询的结果进行后续操作的场景。

      2.使用过滤器: 可以使用基于范围或布尔条件的过滤器,将需要查询的字段作为过滤条件进行搜索。这种方式虽然不能像分词字段那样进行模糊搜索,但能够高效地进行准确匹配。而且,过滤器可以与其他查询方式结合使用,以实现更精确的搜索结果。

      3.使用ngram分析器: 如果需要在非文本字段上进行模糊搜索,可以使用ngram分析器对该字段进行分析处理。即将字符拆分成一组n个连续字符,并对每组字符分别进行索引。这样,在搜索时,可以将查询字符拆分为n个字符组,然后对每组字符进行全文搜索。

      总结:

      • 对于未分词不进行过滤的字段,可使用聚合查询,使用范围或布尔条件过滤器或使用ngram分析器处理模糊搜索。
      评论
    • 码农阿豪 Java领域优质创作者 2024-04-20 18:36
      关注
      让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
      回答: 对于未分词字段或数值等非文本字段,Elasticsearch(以下简称ES)没有倒排索引可供使用。在查询时,ES会默认进行全表扫描。但ES也提供了一些优化措施来提高这些类型字段的查询效率。
      1. 数值型字段 在ES中,如果字段类型为数值型,ES会将其转化为一段有序的二进制位。当查询时,ES会将查询条件转化为类似二进制位的形式,然后在根据这个二进制位进行快速查找,从而达到加速查询的目的。 举例说明: 对于一个有数值型字段“age”的文档,如果我们查询age在25-30岁之间的文档,我们可以使用range查询:
      {
        "query": {
          "range": {
            "age": {
              "gte": 25,
              "lte": 30
            }
          }
        }
      }
      

      此时ES会将这个查询条件转化为一个二进制位,然后在数值型字段的倒排索引中查找符合这个二进制位的文档。由于数值型字段的倒排索引不需要分词,所以这个查询会比文本字段的查询更快一些。 2. 关键字型字段 对于关键字型字段(即未分词字段),ES会使用doc_values(文档值)来加速查询。在索引数据时,ES会将关键字型字段的值存储在doc_values中。这样,当查询时,ES只需要查询这个文档是否包含某个值,而不是像文本字段那样进行分词,再查询倒排索引。 举例说明: 对于一个有关键字型字段“username”的文档,如果我们查询username为“john”的文档,我们可以使用term查询:

      {
        "query": {
          "term": {
            "username": "john"
          }
        }
      }
      

      此时ES会直接查询该文档的doc_values中是否有“john”这个值,而不需要先对查询条件进行分词,再在倒排索引中查询。 总结: 对于非文本型字段(如数值型、关键字型等),ES会使用一些特殊的技术来加速查询,例如使用有序的二进制位进行查询、使用doc_values进行查询等。尽管这些技术没有像文本字段那样的倒排索引那么好用,但是它们仍然可以大幅加速非文本型字段的查询。

      展开全部

      评论
      浮世★繁華 2024-04-20 18:41

      username这个例子按你的意思还是得遍历所有文档查看是否有这个值啊

      回复
    • GISer Liu 2024-04-22 02:13
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      对于
      Elasticsearch(ES)搜索引擎而言,确实,在进行搜索时,通常是根据倒排索引进行的。倒排索引是根据文档中的词项(terms)构建的数据结构,它将每个词项映射到包含该词项的文档列表。这使得在文本字段上进行搜索非常高效,因为可以快速地找到包含特定词项的文档。
      但是,当搜索非文本字段(如未分词字段或数值字段)时,情况会有所不同。对于未分词字段,ES并不会像文本字段那样构建倒排索引,而是将整个字段的值作为一个词项存储在倒排索引中。这意味着搜索未分词字段会导致全文档扫描,而不是利用倒排索引进行快速检索。
      针对这个问题,以下是一些解决思路和解决方案:

      1. 显式声明字段类型 :在创建索引映射时,通过显式声明字段的类型,可以告诉ES如何处理该字段。对于数值字段,可以将其声明为 "integer"、"float" 等类型,以便ES可以正确地对其进行索引和搜索。
      2. 使用过滤器查询 :对于非文本字段,可以使用过滤器查询来进行搜索。过滤器查询可以在不计算相关性得分的情况下,快速过滤文档。这对于数值范围查询等场景非常有效。
      3. 利用映射参数优化 :在字段映射中,可以使用一些参数来优化搜索。例如,index: false 参数可以禁止对该字段建立索引,从而节省空间,但这也意味着无法对该字段进行搜索。
      4. 使用脚本查询 :对于复杂的搜索需求,可以使用脚本查询来执行自定义逻辑。这可以在搜索过程中对非文本字段进行转换或计算,以满足特定需求。
        下面是一个基本的索引映射示例,展示了如何声明一个数值字段和一个未分词字段:
        jsonCopy code
        {
        "mappings": {
        "properties": {
        "numeric_field": {
        "type": "integer"
        },
        "non_analyzed_field": {
        "type": "keyword"
        }
        }
        }
        }
        
        在这个示例中,"numeric_field" 被声明为整数类型,而 "non_analyzed_field"
        被声明为关键字类型,这意味着它是一个未分词字段。
        总的来说,虽然对于非文本字段的搜索无法像文本字段那样利用倒排索引进行优化,但通过合理的映射和查询策略,仍然可以实现高效的搜索功能。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      展开全部

      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    [附源码]计算机毕业设计JAVA校园兼职招聘系统
    IOC操作Bean管理(基于注解方式)
    博客系统(升级(Spring))(一)创建数据库,创建实例化对象,统一数据格式,统一报错信息
    搞直播啦,千视超高清4K NDI编解码器8月3日19:00准时开播
    Kotlin Class 自定义类
    fsync
    java基于springboot+Vue图片分享社区网站
    深入探索Spring Boot的条件装配与条件注解
    电子器件 电阻参数与选型
    GStreamer appsrc 等插件实现视频音频混流,录制和推流
  • 原文地址:https://ask.csdn.net/questions/8091952