ELK(七)ElasticSearch快速入门_全文搜索

全文搜索两个最重要的方面是

  • 相关性 它是评价查询与其结果间的相关程度,并根据这种相关程度对结果排名的一种能力,这种计算方式可以是TF/IDF方法,地理位置临近,模糊相似,或其他的某些算法
  • 分词它是将文本块转换为有区别的,规范化的token的一个过程,目的是为了创建倒排索引以及查询倒排索引

构造数据

  1. 创建索引 使用ik分词器指定要分词的字段
# 创建指定ik分词器的索引
PUT /itcast
{
	"settings":{
		"index":{
			"number_of_shards":"2", 
			"number_of_replicas":"0" 
		}
	},
	"mappings":{
		"person":{
			"properties":{
				"name":{
					"type":"text"
				},
				"age":{
					"type":"integer"
				},
				"mail":{
					"type":"keyword"
				},
				"hobby":{
					"type":"text",
					# 给hobby字段指定使用ik分词器
					"analyzer":"ik_max_word"
				}
			}
		}
	}
}
  1. 使用_bulk命令批量构造数据
POST /itcast/_bulk 
# 注意 这个url中没有指定文档类型
# 新创建的索引 第一次添加数据并且不指定_id使用index进行添加
{"index":{"_index":"itcast","_type":"person"}}
{"name":"张三","age": 20,"mail": "111@qq.com","hobby":"羽毛球,乒乓球,足球"}
{"index":{"_index":"itcast","_type":"person"}}
{"name":"李四","age": 21,"mail": "222@qq.com","hobby":"羽毛球,乒乓球,足球,篮球"}
{"index":{"_index":"itcast","_type":"person"}}
{"name":"王五","age": 22,"mail": "333@qq.com","hobby":"羽毛球,篮球,游泳,听音乐"}
{"index":{"_index":"itcast","_type":"person"}}
{"name":"赵六","age": 23,"mail": "444@qq.com","hobby":"跑步,游泳"}
{"index":{"_index":"itcast","_type":"person"}}
{"name":"孙七","age": 24,"mail": "555@qq.com","hobby":"听音乐,看电影"}

# 别忘了最下面的回车

单词搜索

# 使用match查询 查询非结构化数据
POST /itcast/person/_search

{
	"query":{
		"match":{
			"hobby":"音乐"
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}

过程说明:

  1. 检查字段类型
    爱好hobby字段是一个text类型(指定了IK分词器),这意味着查询字符串本身也应该被分词
  2. 分析查询字符串
    将查询的字符串"音乐"传入IK分词器中,输出的结果是单个项"音乐",因为只有一个单词项,所以match查询执行的是单个底层term查询
  3. 查找匹配文档
    用term查询在倒排索引中查找"音乐"然后获取一组包含该项的文档,本例的结果是文档3,5
  4. 为每个文档评分
    用term查询计算每个文档相关度评分_score,这是种将词频("音乐"这个词在相关文档的hobby字段中出现的频率)和反向文档频率("音乐"这个词在所有文档中hobby字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式

多词搜索

POST /itcast/person/_search

{
	"query":{
		"match":{
			# 多个词中间用空格隔开
			"hobby":"音乐 篮球"
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}
# 这个搜索 搜索出来的是包含音乐或者包含篮球的,但是不是我们想要的结果,我们想要的是即包含音乐又包含篮球的

可以看到,包含了"音乐","篮球"的数据都已经被搜索到了
但是,搜索的结果不符合我们的预期,因为我们想搜索的是即包含"音乐"又包含"篮球"的用户,显然结果返回的是"或"的关系
在Elasticsearch中,可以指定词之间的逻辑关系,如下:

POST /itcast/person/_search
{
	"query":{
		"match":{
			"hobby":{
				"query":"音乐 篮球",
				"operator":"and"
			}
			
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}

前面我们测试了"OR"和"AND"搜索,这是两个极端,其实在实际场景中,并不会选取这两个极端,更有可能是选取这种,或者说,只要符合一定的相似度就可以查询到数据,在ElasticSearch中也支持这样的查询,通过minimum_should_match来指定匹配度,如:70% 如果是and 就设置100% 如果是or就设置50%

POST /itcast/person/_search
{
	"query":{
		"match":{
			"hobby":{
				"query":"游泳 羽毛球",
				#设置匹配度
				"minimum_should_match":"80%"
			}
			
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}

相似度设置多少合适,需要在实际的需求中进行反复测试,才可以得到合理的值

组合搜索

在搜索时,也可以使用过滤器中讲过的bool组合查询

POST /itcast/person/_search
{
	"query":{
		"bool":{
			"must":{
				"match":{
					"hobby":"篮球"
				}
			},
			"must_not":{
				"match":{
					"hobby":"音乐"
				}	
			},
			"should":[
				{
					"match":{
						"hobby":"游泳"
					}
				}	
			]
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}

# 必须包含篮球,必须不包含音乐  ,如果包含游泳那么它的相似度更高

评分的计算规则
bool查询会为每个文档计算相关度评分_score,再将所有匹配的must和should语句的分数_score求和,最后除以must和should语句的总数
must_not语句不会影响评分,它的作用只是将不想管的文档排除

默认情况下,should中的内容不是必须匹配的,如果查询语句中没有must,那么就会至少匹配其中一个.当然,也可以通过minimum_should_match参数进行控制,该值可以是数字(最少匹配几个)也可以是百分比
示例:

POST /itcast/person/_search
{
	"query":{
		"bool":{
			
			"should":[
				{
					"match":{
						"hobby":"游泳"
					}
				},
				{
					"match":{
						"hobby":"篮球"
					}
				},
				{
					"match":{
						"hobby":"音乐"
					}
				}	
			],
			#表示最少匹配两个
			"minimum_should_match":2
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}

minimum_should_match为2 表示should的三个词中,至少要满足两个,而且 上一条bool查询语句中没有must 表示should中的3个词最少要匹配一个,但是已经配置minumum_should_match为2了就把这个默认的覆盖了

权重

有些时候,我们可能需要对某些词增加权重来影响该条数据的得分,

搜索关键字为"游泳 篮球"and关系,如果结果中包含了"音乐"权重为10,包含了"跑步"权重为2

{
	"query":{
		"bool":{
			"must":{
				"match":{
					"hobby":{
						"query":"游泳 篮球",
						"operator":"and"
					}
				}	
			},
			"should":[
				{
					"match":{
						"hobby":{
							"query":"音乐",
							# 设置权重为10 
							"boost":10
						}
					}
				},
				{
					"match":{
						"hobby":{
							"query":"跑步",
							#设置权重为2
							"boost":2
						}
					}
				}
			]
		}
	},
	"highlight":{
		"fields":{
			"hobby":{}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值