elasticsearch多字段搜索
https://blog.csdn.net/Ricky110/article/details/78888711
多字段搜索
多字符串查询
boost 参数 “最佳” 值,较为简单的方式就是不断试错,比较合理的区间处于 1 到 10 之间,当然也有可能是 15 。如果为 boost 指定比这更高的值,将不会对最终的评分结果产生更大影响,因为评分是被 归一化的
GET /_search
{
"query": {
"bool": {
"should": [
{ "match": {
"title": {
"query": "War and Peace",
"boost": 2
}}},
{ "match": {
"author": {
"query": "Leo Tolstoy",
"boost": 2
}}},
{ "bool": { # 不写在上面一层,是因为tarnslator理论是只占总评分的三分之一,在上面一层就是四分之一了
"should": [
{ "match": { "translator": "Constance Garnett" }},
{ "match": { "translator": "Louise Maude" }}
]
}}
]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
最佳字段
dis_max(Disjunction Max Query)查询,意思是 或,指的是: 将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回;为了理解这句话,做给小实验
创建测试数据
DELETE my_index
PUT /my_index/my_type/1
{
"title": "Quick brown fox rabbits",
"body": "Brown eats rabbits are commonly seen."
}
PUT /my_index/my_type/2
{
"title": "Keeping pets healthy",
"body": "My quick brown fox eats rabbits on a regular basis."
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
查询比较
GET /my_index/my_type/_search
{
"query": {
"bool": {
"should": [
{ "match": { "title": "Brown fox eats" }},
{ "match": { "body": "Brown fox eats" }}
]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
结果:id为1的文档在前面
GET /my_index/my_type/_search
{
"query": {
"dis_max": { # dis_max查询,文档查询的某个match评分最高的作为结果返回
"queries": [
{ "match": { "title": "Brown fox eats" }},
{ "match": { "body": "Brown fox eats" }}
]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
结果:
最佳字段查询调优
tie_breaker:一个简单的 dis_max 查询会采用单个最佳匹配字段, 而忽略其他的匹配,指定 tie_breaker 这个参数可以将其他匹配语句的评分也考虑其中;比如:
简单dis_max查询
{
"query": {
"dis_max": {
"queries": [
{ "match": { "title": "Quick pets" }},
{ "match": { "body": "Quick pets" }}
]
}
}
}
1
2
3
4
5
6
7
8
9
10
结果:
tie_breaker
GET /my_index/my_type/_search
{
"query": {
"dis_max": {
"queries": [
{
"match": {
"title": "Quick pets"
}
},
{
"match": {
"body": "Quick pets"
}
}
],
"tie_breaker": 0.3
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
结果:
tie_breaker 参数提供了一种 dis_max 和 bool 之间的折中选择,范围[0,1]范围建议0.1-0.4, 0 代表使用 dis_max 最佳匹配语句的普通逻辑, 1 表示所有匹配语句同等重要,步骤如下:
获得最佳匹配语句的评分 _score
将其他匹配语句的评分结果与 tie_breaker 相乘
对以上评分求和并规范化
multi_match查询
为能在多个字段上反复执行相同查询提供了一种便捷方式,multi_match 多匹配查询的类型有多种,其中的三种恰巧与 了解我们的数据 中介绍的三个场景对应,即: best_fields 、 most_fields 和 cross_fields (最佳字段、多数字段、跨字段),默认情况下,查询的类型是 best_fields , 这表示它会为每个字段生成一个 match 查询,然后将它们组合到 dis_max 查询的内部
GET /my_index/my_type/_search
{
"query": {
"dis_max": {
"queries": [
{
"match": {
"title": {
"query": "Quick brown fox",
"minimum_should_match": "30%"
}
}
},
{
"match": {
"body": {
"query": "Quick brown fox",
"minimum_should_match": "30%"
}
}
}
],
"tie_breaker": 0.3
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
查询等价于
GET /my_index/my_type/_search
{
"query": {
"multi_match": {
"query": "Quick brown fox",
"type": "best_fields", # 默认为best_fields可以不指定
"fields": [
"title",
"body"
],
"tie_breaker": 0.3,
"minimum_should_match": "30%" # 这样的参数会被传递到生成的 match 查询中
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
结果:
查询字段名称的模糊匹配
字段名称可以用模糊匹配的方式给出
{
"multi_match": {
"query": "Quick brown fox",
"fields": "*_title"
}
}
1
2
3
4
5
6
提升单个字段的权重
可以使用 ^ 字符语法为单个字段提升权重,在字段名称的末尾添加 ^boost
{
"multi_match": {
"query": "Quick brown fox",
"fields": [ "*_title", "chapter_title^2" ]
}
}
1
2
3
4
5
6
多字段映射
是对我们的字段索引两次, 一次使用词干模式以及一次非词干模式
添加多字段映射
DELETE /my_index
PUT /my_index
{
"settings": { "number_of_shards": 1 },
"mappings": {
"my_type": {
"properties": {
"title": {
"type": "string",
"analyzer": "english",
"fields": {
"std": {
"type": "string",
"analyzer": "standard"
}
}
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Put值
PUT /my_index/my_type/1
{ "title": "My rabbit jumps" }
PUT /my_index/my_type/2
{ "title": "Jumping jack rabbits" }
1
2
3
4
5
get title
GET /my_index/_search
{
"query": {
"match": {
"title": "jumping rabbits"
}
}
}
# 结果命中2条
1
2
3
4
5
6
7
8
9
10
11
get title.std
GET /my_index/_search
{
"query": {
"match": {
"title.std": "jumping rabbits"
}
}
}
# 结果命中1条
1
2
3
4
5
6
7
8
9
most_fields 合并两次索引的评分,加权重
GET /my_index/_search
{
"query": {
"multi_match": {
"query": "jumping rabbits",
"type": "most_fields",
"fields": [ "title^10", "title.std" ]
}
}
}
1
2
3
4
5
6
7
8
9
10
跨字段实体搜索
当多个属性结合起来决定一个事物的时候,可以使用multi_match查询(依次查询每个字段并将每个字段的匹配评分结果相加),比如
以下字段表示一个人信息
{
"street": "5 Poland Street",
"city": "London",
"country": "United Kingdom",
"postcode": "W1V 3DG"
}
1
2
3
4
5
6
可以如下查询
{
"query": {
"bool": {
"should": [
{ "match": { "street": "Poland Street W1V" }},
{ "match": { "city": "Poland Street W1V" }},
{ "match": { "country": "Poland Street W1V" }},
{ "match": { "postcode": "Poland Street W1V" }}
]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
或
{
"query": {
"multi_match": {
"query": "Poland Street W1V",
"type": "most_fields", # 合并所有匹配字段的评分
"fields": [ "street", "city", "country", "postcode" ]
}
}
}
1
2
3
4
5
6
7
8
9
most_fields也存在些问题
是为多数字段匹配 任意 词设计的,而不是在 所有字段 中找到最匹配的
不能使用 operator 或 minimum_should_match 参数来降低次相关结果造成的长尾效应
词频对于每个字段是不一样的,而且它们之间的相互影响会导致不好的排序结果
自定义_all
copy_to 参数来实现给字段添加自定义_all字段
PUT /my_index
{
"mappings": {
"person": {
"properties": {
"first_name": {
"type": "string",
"copy_to": "full_name"
},
"last_name": {
"type": "string",
"copy_to": "full_name"
},
"full_name": {
"type": "string"
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
可通过地址http://blog.csdn.net/jiao_fuyou/article/details/49800969来更深入学习_all
cross-fields跨字段查询
自定义 _all 的方式是一个好的解决方案,只需在索引文档前为其设置好映射,然而还可以使用cross_fields 类型进行 multi_match 查询
cross_fields 使用词中心式(term-centric)的查询方式,这与 best_fields 和 most_fields 使用字段中心式(field-centric)的查询方式非常不同
字段中心式
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "most_fields",
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
对于匹配的文档, peter 和 smith 都必须同时出现在相同字段中,要么是 first_name 字段,要么 last_name 字段
(+first_name:peter +first_name:smith)
(+last_name:peter +last_name:smith)
1
2
词中心式,词 peter 和 smith 都必须出现,但是可以出现在任意字段中,cross_fields 类型首先分析查询字符串并生成一个词列表,然后它从所有字段中依次搜索每个词
GET /_validate/query?explain
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"operator": "and",
"fields": [ "first_name", "last_name" ]
}
}
}
1
2
3
4
5
6
7
8
9
10
11
为了让 cross_fields 查询以最优方式工作,所有的字段都须使用相同的分析器
采用 cross_fields 查询与 自定义 _all 字段 相比,其中一个优势就是它可以在搜索时为单个字段提升权重
GET /books/_search
{
"query": {
"multi_match": {
"query": "peter smith",
"type": "cross_fields",
"fields": [ "title^2", "description" ]
}
}
}
1
2
3
4
5
6
7
8
9
10
需要在 multi_match 查询中避免使用 not_analyzed 字段
---------------------
作者:Ricky110
来源:CSDN
原文:https://blog.csdn.net/Ricky110/article/details/78888711
版权声明:本文为博主原创文章,转载请附上博文链接!
elasticsearch多字段搜索的更多相关文章
- Elasticsearch 全字段搜索_all,query_string查询,不进行分词
最近在使用ELasitcsearch的时候,需要用到关键字搜索,因为是全字段搜索,就需要使用_all字段的query_string进行搜索. 但是在使用的时候,遇到问题了.我们的业务并不需要分词,我在 ...
- [Elasticsearch] 多字段搜索 (五) - 以字段为中心的查询
以字段为中心的查询(Field-centric Queries) 上述提到的三个问题都来源于most_fields是以字段为中心(Field-centric),而不是以词条为中心(Term-centr ...
- [Elasticsearch] 多字段搜索 (一) - 多个及单个查询字符串
多字段搜索(Multifield Search) 本文翻译自官方指南的Multifield Search一章. 查询很少是只拥有一个match查询子句的查询.我们经常需要对一个或者多个字段使用相同或者 ...
- Elasticsearch 多字段搜索
查询很少是对一个字段做 match 查询,通常都是一个 query 查询多个字段,比如一个 doc 有 title.content.pagetag 等文本字段,要在这些字段查询含多个 term 的 q ...
- [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段 <译>
multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在“了解你的数据”一节中提 ...
- [Elasticsearch] 多字段搜索 (六) - 自定义_all字段,跨域查询及精确值字段
自定义_all字段 在元数据:_all字段中,我们解释了特殊的_all字段会将其它所有字段中的值作为一个大字符串进行索引.尽管将所有字段的值作为一个字段进行索引并不是非常灵活.如果有一个自定义的_al ...
- [Elasticsearch] 多字段搜索 (三) - multi_match查询和多数字段
multi_match查询 multi_match查询提供了一个简便的方法用来对多个字段执行相同的查询. NOTE 存在几种类型的multi_match查询,其中的3种正好和在"了解你的数据 ...
- [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优
最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...
- [Elasticsearch] 多字段搜索 (二) - 最佳字段查询及其调优(转)
最佳字段(Best Fields) 假设我们有一个让用户搜索博客文章的网站,就像这两份文档一样: PUT /my_index/my_type/1 { "title": " ...
随机推荐
- mount挂载相关参数详解
mount [ -t 设备类型 ] [ -o 扩展参数 ] dev dir -t:指定mount挂载设备类型,常见的类型有nfs.ntfs.vfat.iso9660等: is09 ...
- JS运算符、NaN
一.关系运算符 (< <= > >= == === != !==) 判断符号左右的两个数据的大小之间的关系,运算结果是一个布尔类型的值 == 只判断值 ===即判断值并且 ...
- ACTIVEMQ 实例化到MSSQL
实例化文章很多,不重复,自行查询 直接上XML <!-- Licensed to the Apache Software Foundation (ASF) under one or more c ...
- Tomcat在Window控制台下启动时乱码的两种解决办法
在命令提示符中启动Tomcat时,日志窗口出现乱码: 乱码的原因肯定是日志解码错误引起的,因此就有一系列问题: 1.这个窗口的文本编码是什么? 窗口的文本编码查看:右击窗口>选项 可以看到窗口的 ...
- javascript自定义一个全类型读取的函数
我爱撸码,撸码使我感到快乐!大家好,我是Counter.因为我们知道,在JavaScript中有自带的方法可以读取类型,但是不很全面,今天来分享下如何自己定义一个函数,将所有传入参数的类型给打印出来, ...
- XSS漏洞学习笔记
XSS漏洞学习 简介 xss漏洞,英文名为cross site scripting. xss最大的特点就是能注入恶意的代码到用户浏览器的网页上,从而达到劫持用户会话的目的. 说白了就是想尽办法让你加载 ...
- (Code) Python implementation of phrase extraction from sentence
import os import numpy as np import pandas as pd from tqdm import tqdm import numpy as np import str ...
- 常见的JavaWeb安全问题及修复
1.SQL注入:程序向后台数据库传递SQL时,用户提交的数据直接拼接到SQL语句中并执行,从而导入SQL注入攻击. 字符型注入:黑色部分为拼接的问题参数 select * from t_user wh ...
- MySQL中使用union all获得并集的排序
项目中有时候因为某些不可逆转的原因使得表中存储的数据难以满足在页面中的展示要求.之前的项目上有文章内容的展示功能,文章分为三个状态待发布.已发布.已下线.他们在数据表中判断状态的字段(PROMOTE_ ...
- 基于redis的分布式锁(转)
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...