源码地址
springboot2教程系列
ElasticSearch6.x安装、ElasticSearch head插件
org.springframework.boot
spring-boot-starter-data-elasticsearch
spring:
data:
elasticsearch:
# 集群名
cluster-name: elasticsearch
# 连接节点,注意在集群中通信都是9300端口,否则会报错无法连接上!
# cluster-nodes: 10.10.2.139:9300
cluster-nodes: 10.10.2.139:9300
# 是否本地连接
local: false
repositories:
# 仓库中数据存储
enabled: true
@Document(indexName = "nias12",type = "receiver3",refreshInterval="120s",replicas=1)
@Data
public class BusReceiverEntity {
//主键
private Long id;
//姓名
private String name;
//区域
private String regionCode;
//地址
@Field(type = FieldType.Text, analyzer = "ik_smart",
searchAnalyzer = "ik_smart", fielddata=true)
private String address;
//地址英文名字
private String enName;
//家庭成员
@Field(type = FieldType.Integer)
private int memberFamily;
//创建时间
private Date createDate;
public BusReceiverEntity(){
}
}
@Document注解里面的几个属性,类比mysql的话是这样: index –> DB
type –> Table
Document –> row
@Component
public interface ReceiverRepository extends ElasticsearchRepository<BusReceiverEntity,Long> {
}
@Service
public class BusReceiverServiceImp implements BusReceiverService{
@Autowired
ReceiverRepository receiverRepository;
@Override
public void save(BusReceiverEntity t) {
receiverRepository.save(t);
}
}
@RestController
public class ElasticSearchController {
@Autowired
BusReceiverService busReceiverService;
@RequestMapping("/save")
public String save(){
busReceiverService.save(NameBuildUtils.buildReceiver());
return "save";
}
}
标准分析器是默认分析器,如果没有指定,则使用标准分析器。它提供了基于语法的标记化(基于Unicode标准附件29中指定的Unicode文本分割算法),对大多数语言都很有效。
只要遇到不是字母的字符,这个简单的分析器就会将文本分解成术语。所有项都是小写的。
更多的查看
POST _analyze
{
"analyzer": "standard",
"text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone."
}
集成的中文分词器Ikanalyzer中提供的Analyzer:ik_smart 、 ik_max_word
内建的和集成的analyzer可以直接使用。如果它们不能满足我们的需要,则我们可自己组合字符过滤器、分词器、词项过滤器来定义自定义的analyzer
PUT test_index1
{
"settings": {
"analysis": {
"analyzer": {
"my_ik_analyzer": {
"type": "custom",
"tokenizer": "ik_smart",
"char_filter": [
"html_strip"
],
"filter": [
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "analysis/synonym.txt"
}
}
}
}
}
PUT test_index1/_mapping/_doc
{
"properties": {
"title": {
"type": "text",
"analyzer": "my_ik_analyzer"
}
}
}
PUT test_index1/_doc/1
{
"title": "联想是全球最大的笔记本厂商"
}
//搜索
GET /test_index1/_search
{
"query": {
"term": {
"title": "张三"
}
}
}
{
"settings": {
"analysis": {
"analyzer": {
"default": {
"tokenizer": "ik_smart",
"filter": [
"synonym"
]
}
},
"filter": {
"synonym": {
"type": "synonym",
"synonyms_path": "analysis/synonym.txt"
}
}
}
},
"mappings": {
"_doc": {
"properties": {
"title": {
"type": "text"
}
}
}
}
}
我们可以为每个查询、每个字段、每个索引指定分词器。
在索引阶段ES将按如下顺序来选用分词:
首先选用字段mapping定义中指定的analyzer
字段定义中没有指定analyzer,则选用 index settings中定义的名字为default 的analyzer。
如index setting中没有定义default分词器,则使用 standard analyzer.
**tokenizer:**分词器,对文本进行分词。一个analyzer必需且只可包含一个tokenizer。
**character filter :**字符过滤器,对文本进行字符过滤处理,如处理文本中的html标签字符。处理完后再交给tokenizer进行分词。一个analyzer中可包含0个或多个字符过滤器,多个按配置顺序依次进行处理。
**token filter:**词项过滤器,对tokenizer分出的词进行过滤处理。如转小写、停用词处理、同义词处理。一个analyzer可包含0个或多个词项过滤器,按配置顺序进行过滤。
curl -XPOST http://10.10.2.139:9200/_analyze
{
"tokenizer": "path_hierarchy",
"text": "联想是全球最大的笔记本厂商"
}
es内建的分词器
英文的处理能力同于StopAnalyzer.支持中文采用的方法为单字切分。他会将词汇单元转换成小写形式,并去除停用词和标点符号。
仅仅是去除空格,对字符没有lowcase化,不支持中文; 并且不对生成的词汇单元进行其他的规范化处理。
KeywordAnalyzer把整个输入作为一个单独词汇单元,方便特殊类型的文本进行索引和检索。针对邮政编码,地址等文本信息使用关键词分词器进行索引项建立非常方便
在遇到非字母的字符时将文本分成 ,支持中文
更多请查看官网
ik 带有两个分词器
会将文本做最细粒度的拆分;尽可能多的拆分出词语
会做最粗粒度的拆分;已被分出的词语将不会再次分词
召回率:搜索的时候,增加能够搜索到的结果的数量
curl -XPUST http://10.10.2.139:9200/test_index3
{
"settings": {
"index" : {
"analysis" : {
"analyzer" : {
"standard_stop" : {
"tokenizer" : "standard",
"filter" : ["my_stop"]
}
},
"filter" : {
"my_stop" : {
"type" : "stop",
"stopwords": ["联", "is", "the"]
}
}
}
}
}
}
curl -XPOST http://10.10.2.139:9200/test_index3/_analyze
{
"analyzer": "standard_stop",
"text": "联想是全球最大的笔记本厂商"
}
##结果忽略联的分词
说明:中文分词器Ikanalyzer中自带有停用词过滤功能
curl -XPUST http://10.10.2.139:9200/test_index4
{
"settings": {
"index" : {
"analysis" : {
"analyzer" : {
"my_ik_synonym" : {
"tokenizer" : "ik_smart",
"filter" : ["synonym"]
}
},
"filter" : {
"synonym" : {
"type" : "synonym",
"synonyms_path" : "analysis/synonym.txt"
}
}
}
}
}
}
注意:文件一定要UTF-8编码(synonyms_path的目录为elasticsearch.yml所在目录)
analysis/synonym.txt
张三,李四
电饭煲,电饭锅 => 电饭煲
电脑 => 计算机,compute
curl -XPOST http://10.10.2.139:9200/test_index4/_analyze
{
"analyzer": "my_ik_synonym",
"text": "我想买个电饭锅和一个电脑"
}
分词结果会把电脑改变为计算机和compute两个词,把电饭锅转换为电饭煲
更多的词项过滤器
**html_strip :**过滤html标签,解码HTML entities like &. 例子
mapping :用指定的字符串替换文本中的某字符串。 例子
**pattern_replace :**进行正则表达式替换。 例子
文档
10.10.2.139:9200
GET /test/_segments
curl -XPUT IP:9200/索引名称(小写)
curl -XPUT IP:9200/索引名称/
{
"settings":{
"number_of_shards":1,
"number_of_replicas":2,
"index":{
"analysis":{
"analyzer":{
"default":{
"tokenizer":"standard",
"filter":[
"asciifolding",
"lowercase",
"ourEnglishFilter"
]
}
},
"filter":{
"ourEnglishFilter":{
"type":"kstem"
}
}
}
}
}
}
3.删除索引
DELETE /my_index
//删除所有的索引
curl -XDELETE http://localhost:9200/_all
或 curl -XDELETE http://localhost:9200/*
//一次删除多个索引
curl -XDELETE http://localhost:9200/twitter,my_index
action.destructive_requires_name = true
Elasticsearch 6.x Mapping设置
Elasticsearch 映射参数 fields
term 查询会查找我们指定的精确值。term 查询是简单的,它接受一个字段名以及我们希望查找的数值。
POST nias12/_search
{
"query" : {
"term" : {
"name.keyword" : "牧文景"
}
}
}
由于“牧文景”使用的是内置默认分词器,会分词为“牧”,“文”,“景”,而查询条件是不会分词查询,所以如果为"name" : "牧文景"
查不到文档。
name.keyword
不分词,所以能配精确匹配。
当进行精确值查找时, 我们会使用过滤器(filters)。过滤器很重要,因为它们执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。如下: 使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。
{
"query" : {
"constant_score" : {
"filter" : {
"term" : {
"name.keyword" : "牧文景"
}
}
}
}
}
{
"query" : {
"terms" : {
"name.keyword" : ["卓巧兰","潘昆锐"]
}
}
}
terms是包含的意思,包含"卓巧兰"或者包含"潘昆锐"。
exist查询某个字段是否存在
{
"query" : {
"exists" : { "field" : "name" }
}
}
{ "query": {
"prefix" : { "name.keyword" : "牧" }
}
}
如果是分词的字段,则搜索每个分词项的前缀。
{
"query": {
"wildcard" : { "address" : "?徽" }
}
}
如果是分词的字段,则搜索每个分词项的通配符检索。
匹配具有匹配通配符表达式( (not analyzed )的字段的文档。 支持的通配符:
1)*,它匹配任何字符序列(包括空字符序列);
2)?,它匹配任何单个字符。
请注意,此查询可能很慢,因为它需要遍历多个术语。
为了防止非常慢的通配符查询,通配符不能以任何一个通配符*或?开头。
模糊查询可以在Match和 Multi-Match查询中使用以便解决拼写的错误,模糊度是基于Levenshteindistance计算与原单词的距离。
{
"query": {
"multi_match" : {
"query" : "牧本景",//不存在
"fields": ["name.keyword"],
"fuzziness": "AUTO"
}
},
"_source": ["name"],
"size": 1
}
上面我们将fuzziness的值指定为AUTO,其在term的长度大于5的时候相当于指定值为2,然而80%的人拼写错误的编辑距离(edit distance)为1,所有如果你将fuzziness设置为1可能会提高你的搜索性能
multi_match关键字通常在查询多个fields
的时候作为match关键字的简写方式。
{
"query": {
"multi_match" : {
"query" : "夔易文",
"fields" : ["name.keyword","name"]
}
}
}
GET /index/_search
{
"from": 30,
"size": 10
}
查询
为什么Elasticsearch查询变得这么慢了?