喵星之旅-狂奔的兔子-使用kibana对es进行查询

match系列

match关键字,相当于mysql数据库中的like查询,match查询的字段如果是text类型,那么text会被分词,match就会匹配分词,查询所有包含分词的doc文档,如果不是text类型的,那就是精确查询。

match:查询指定条件的数据,match会将查询的条件进行分词操作,然后doc文档中包含分词,就都会查询出来。
match_all:查询所有数据。
match_phrase:匹配短语,match是会查询所有包含分词的doc文档,而match_phrase则是匹配整个短语,才会返回对应的doc文档。但是这个与“ik_max_word”分词器有冲突,很可能失败,不排除有的版本可以。由于我选择的分词器就是“ik_max_word”,所以相关验证跳过。
match_phrase_prefix:匹配短语的前缀部分,这个只能使用在text类型字段。

# 查询bunny索引中title包含"提高效率"的数据,前提是该字段已经分词,并且会对查询条件进行分词。实际查询结果是包含“提高效率”,“提高”,“高效率”,“高效”,“效率”的数据。
GET /bunny/_search
{
  "query": {
    "match": {
      "title": "提高效率"
    }
  }
}

# 查询bunny索引中所有数据
get /bunny/_search
{
  "query": {
    "match_all": {}
  }
}


排序查询

elasticsearch支持对搜索结果排序,默认是根据相关度算分(_score)来排序。
不是所有字段都可以排序,只能是数字字段。

get /bunny/_search
{
  "query": {
    "match_all": {}
  },
  "sort":  [
    {
      "createTime": {
        "order": "desc"
      }
    }
  ]
}

分页查询

elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。 elasticsearch中通过修改from、size参数来控制要返回的分页结果:

# 跳过80条数据,从第81条开始显示最多10条。如果是默认的应该是0,10.
GET /ky_technical_product/_search
{
  "query": {
    "match": {
      "title": "提高 效率"
    }
  } ,
  "from": 80, 
  "size": 10
}

bool查询

es bool 查询是把任意多个简单查询组合在一起,使用 must、should、must_not、filter 选项来表示简单查询之间的逻辑,每个选项都可以出现 0 次到多次。它是为了满足现实中比较复杂的查询需求,如需要在多个字段上查询多种多样的文本,并且根据一系列的标准来过滤。

bool query 主要通过下列 4 个选项来构建用户想要的布尔查询,每个选项的含义如下:

must:文档必须匹配,该选项下的查询条件,相当于逻辑运算的 AND,且参与文档相关度的评分。
should:文档可以匹配 should 选项下的查询条件也可以不匹配,相当于逻辑运算的 OR,且参与文档相关度的评分。
must_not:与 must 相反,匹配该选项下的查询条件的文档不会被返回;需要注意的是,must_not 语句不会影响评分,它的作用只是将不相关的文档排除。
filter:和 must 一样,匹配 filter 选项下的查询条件的文档才会被返回,但是 filter 不评分,只起到过滤功能,与 must_not 相反。

这里需要说明的是,每一个子查询都独自地计算文档的相关性得分。一旦他们的得分被计算出来, bool 查询就将这些得分进行合并并且返回一个代表整个布尔操作的得分。具体的得分规则在下面的评分计算章节中介绍。

must 语句必须匹配,但有多少 should 语句应该匹配呢?默认情况下,没有 should 语句是必须匹配的,但只有一个例外,那就是当没有 must 语句的时候,至少有一个 should 语句必须匹配。

计算规则

bool 查询采用“匹配越多越好(more_matches_is_better)”的机制,因此满足 must 和 should 子句的文档将会合并起来计算分值。
在 filter 子句查询中,分值将会都返回 0。
must_not 子句并不影响得分,它们存在的意义是排除已经被包含的文档。

如上所述,bool 查询的计算得分主要是 must 和 should 子句,它们的计算规则是,把所有符合 must 和 should 的子句得分加起来,然后乘以匹配子句的数量,再除以子句的总数。

# groundingState="已上架" and "category"<>"暂无" and "title"包含 "钻井" and ("createByName"包含"管理" or "content"包含"石油")。其中groundingState没有分词。
GET /bunny/_search
{
  "query": {
    "bool": {
      "filter": {
        "term": { "groundingState.keyword": "已上架" }
      },
      "must_not": {
        "term": { "category": "暂无" }
      },
      "must": {
        "match": { "title": "钻井" }
      },
      "should": [
        {
          "match": { "createByName": "管理" }
        },
        {
          "match": { "content": "石油" }
        }
      ]
    }
  }
}

高亮显示

GET /bunny/_search
{
  "query": {
    "match": {
      "title": "钻井"
    }
  },
   "highlight": {
    "fields": {
      "title": {
      }
    }
  }
}

elasticsearch 提供了如下高亮参数:

boundary_chars	包含每个边界字符的字符串。默认为,! ?\ \ n。
boundary_max_scan	扫描边界字符的距离。默认为20。
boundary_scanner	指定如何分割突出显示的片段,支持chars、sentence、word三种方式。
boundary_scanner_locale	用来设置搜索和确定单词边界的本地化设置,此参数使用语言标记的形式(“en-US”, “fr-FR”, “ja-JP”)
encoder	表示代码段应该是HTML编码的:默认(无编码)还是HTML (HTML-转义代码段文本,然后插入高亮标记)
fields	指定检索高亮显示的字段。可以使用通配符来指定字段。例如,可以指定comment_*来获取以comment_开头的所有文本和关键字字段的高亮显示。
force_source	根据源高亮显示。默认值为false。
fragmenter	指定文本应如何在突出显示片段中拆分:支持参数simple或者span。
fragment_offset	控制要开始突出显示的空白。仅在使用fvh highlighter时有效。
fragment_size	字符中突出显示的片段的大小。默认为100。
highlight_query	突出显示搜索查询之外的其他查询的匹配项。这在使用重打分查询时特别有用,因为默认情况下高亮显示不会考虑这些问题。
matched_fields	组合多个匹配结果以突出显示单个字段,对于使用不同方式分析同一字符串的多字段。所有的matched_fields必须将term_vector设置为with_positions_offsets,但是只有将匹配项组合到的字段才会被加载,因此只有将store设置为yes才能使该字段受益。只适用于fvh highlighter。
no_match_size	如果没有要突出显示的匹配片段,则希望从字段开头返回的文本量。默认为0(不返回任何内容)。
number_of_fragments	返回的片段的最大数量。如果片段的数量设置为0,则不会返回任何片段。相反,突出显示并返回整个字段内容。当需要突出显示短文本(如标题或地址),但不需要分段时,使用此配置非常方便。如果number_of_fragments为0,则忽略fragment_size。默认为5。
order	设置为score时,按分数对突出显示的片段进行排序。默认情况下,片段将按照它们在字段中出现的顺序输出(order:none)。将此选项设置为score将首先输出最相关的片段。每个高亮应用自己的逻辑来计算相关性得分。
phrase_limit	控制文档中所考虑的匹配短语的数量。防止fvh highlighter分析太多的短语和消耗太多的内存。提高限制会增加查询时间并消耗更多内存。默认为256。
pre_tags	与post_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
post_tags	与pre_tags一起使用,定义用于突出显示文本的HTML标记。默认情况下,突出显示的文本被包装在和标记中。指定为字符串数组。
require_field_match	默认情况下,只突出显示包含查询匹配的字段。将require_field_match设置为false以突出显示所有字段。默认值为true。
tags_schema	设置为使用内置标记模式的样式。
type	使用的高亮模式,可选项为unified、plain或fvh。默认为unified。

如果我们想使用自定义标签,在高亮属性中给需要高亮的字段加上 pre_tags 和 post_tags 即可。例如:

GET /bunny/_search
{
  "query": {
    "match": {
      "title": "钻井"
    }
  },
   "highlight": {
    "fields": {
      "title": {
        "pre_tags": ["<strong>"],
        "post_tags": ["</strong>"]
      }
    }
  }
}

关于搜索高亮,还需要掌握如何设置多字段搜索高亮。比如,搜索 title 字段的时候,我们期望 description 字段中的关键字也可以高亮,这时候就需要把 require_field_match 属性的取值设置为 fasle。require_field_match 的默认值为 true,只会高亮匹配的字段。多字段高亮的查询语句如下

GET /bunny/_search
{
  "query": {
    "match": {
      "title": "暂无 钻井"
    }
  },
   "highlight": {
    "require_field_match": "false",
    "fields": {
      "title": {
      },
      "category": {
      }
    }
  }
}

高亮返回结果只有匹配上的才会显示,高亮的字段要支持分词,可能是下面两种可能:

      "highlight" : {
          "title" : [
            "<em>钻井</em>优化新技术如何提高<em>钻井</em>效率"
          ],
          "category" : [
            "<em>暂无</em>"
          ]
        }


      "highlight" : {
          "title" : [
            "<em>钻井</em>"
          ]
        }

term查询

term query会去倒排索引中寻找确切的term,它并不知道分词器的存在,这种查询适合keyword、numeric、date等明确值的,分词的字段也可以使用。下面的title就是分词字段。

# 查询包含“提高效率”的,不分词。
GET /bunny/_search
{
  "query": {
    "term": {
      "title": "提高效率"
    }
  }
}

# title= "提高效率",严格相等的条件
GET /bunny/_search
{
  "query": {
    "term": {
      "title.keyword": "提高效率" 
    }
  }
}

# 包含多个值的用terms
GET /bunny/_search
{
  "query": {
    "terms": {
      "title": ["效率" ,"提高"]
    }
  }
}

权重设置

需要根据用户输入的查询关键字同时去匹配多个字段,并且希望对匹配字段的权重做不同的设置,比如同时去匹配公司名称和公司简介,这里一般需要提升公司名称匹配的权重,这样得出的相关性评分才会更准确。
在ES中,我们可以通过boost参数来控制多字段查询的权重。

boost是一个用来修改文档的相关性的参数,默认值是1。可以通过设置不同的值,提升该字段在相关性评分的权重。

boost有两种类型:索引期间boost、查询期间boost。

创建索引时指定的boost参数是存储在索引中的,修改boost值唯一的方法是重新索引这篇文档。

索引期间boost

PUT bunny
{
  "mappings": {
    "properties": {
      "company": {
        "type": "text", "analyzer": "ik_smart", "boost":"3"
      },
      "desc": {
        "type": "text", "analyzer": "ik_smart"
      }
    }
  }
}

GET bunny/_search
{
  "query": {
    "multi_match": {
      "query": "喵星",
      "fields": ["company","desc"]
    }
  }
}

查询期间boost

通过字段名称后面添加“^”符号和boost的值,提升指定字段的评分权重。

GET bunny/_search
{
  "query": {
    "multi_match": {
      "query": "喵星",
      "fields": ["company^3","desc"]
    }
  }
}

java API中权重控制

    Map<String,Float> fields = new HashMap(2);
    fields.put("company", 3.0f);
    fields.put("desc", 1.0f);
    queryBuilder.must(QueryBuilders.multiMatchQuery(paramsDto.getKeyword()).fields(fields).analyzer("ik_smart"));
posted @ 2022-04-25 16:34  喵星兔  阅读(55)  评论(0编辑  收藏  举报