Elasticsearch使用的是一种称为倒排索引的结构,采用Lucene倒排索引作为底层。这种结构适用于快速的全文检索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。
实例:
对以下三个文档构造倒排索引。
倒排索引-组成
单词词典(Term Dictionary)倒排列表(Posting List)
ES存储的是一个JSON格式的文档,其中包含多个字段,每个字段会有自己的倒排索引。
倒排索引的结构
包含这个关键词的document list包含这个关键词的所有document的数量:IDF(inverse document frequency)这个关键词在每个document中出现的次数:TF(term frequency)这个关键词在这个document中的次序每个document的长度:length norm包含这个关键词的所有document的平均长度
倒排索引不可变的好处
不需要锁,提升并发能力,避免锁的问题数据不变,一直保存在os cache中,只要cache内存足够filter cache一直驻留在内存,因为数据不变可以压缩,节省cpu和io开销 2,分词
analysis——文本分析是把全文转换成一系列单词(term/token)的过程,也叫分词
analysis是通过Analyzer来实现的。可使用Elasticsearch内置的分析器/或者定制化分析器。
使用_analyzer API
GET _analyze { "analyzer":"ik_smart", "text":"我是一名Java开发工程师" } # analyzer:指定哪种分词器 # text: 要测试的文本
默认的es分词器对中文的分词不友好,我们会使用插件,ik分词器。
安装ik分词器步骤
官网下载路径是在githup上:https://github.com/medcl/elasticsearch-analysis-ik
官网下载的ik分词器的版本要与ES的版本一致下载的zip文件解压后放到plugins下新建的一个ik文件夹下面在plugins路径下,终端使用ls -a命令查看删除.DS_Store文件重启es即可 3,匹配度
在es查询结果中, 有一个‘_score’字段,这个是匹配度分数的意思。分数越高,结果越靠前。
由ES打分算法得出来的。
二、Rest风格的执行命令 1,字段类型(核心基础类型,还有其他复杂类型)
字符串类型:text,keyword
数字类型:long,integer,short,byte,double,float,half_float,scaled_float
日期类型:date
布尔类型:boolean
二进制类型:binary
2,创建一个索引创建索引并指定mapper
# demotest 是索引名称 # settings 设置了主分片和副本的数量 # mappings 是映射字段,_doc是索引类型,可以自定义命名 # 注意点,本语法是在7.14.1版本,因此要使用‘include_type_name=true’ # 其实,没有特殊要求,mappings可以不用设置,插入数据时会自动创建 PUT /demotest?include_type_name=true { "settings": { "number_of_replicas": 1, "number_of_shards": 2 }, "mappings": { "_doc": { "properties": { "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "age": { "type": "integer" }, "sex": { "type": "text" } } } } }3,新增一条文档
# 指定id的方式添加 PUT demotest/_doc/1 { "name": "张三", "age": "16", "sex": "man" } # 不指定id的方法添加,id会自动生成 POST demotest/_doc { "name": "李四", "age": "17", "sex": "man" }4,修改一条文档
# 方式一,和添加一条文档命名一样,当id存在,则是更新了 PUT demotest/_doc/1 { "name": "李四", "age": "19", "sex": "man" } # 方式二、使用POST加_update方式,注意需要一个doc包裹更新的字段 POST demotest/_doc/1/_update { "doc": { "sex": "woman" } } # 两者的区别,PUT方式修改的话,如果某个字段不传,那么这条数据的字段就被替换为空 # 所以修改 *** 作使用POST的方式更好5,删除一条文档
# 指定索引和id的方式删除 DELETE demotest/_doc/16,查看所有文档
# 更多查询的 *** 作后面详解 GET demotest/_search三、关于文档的基本 *** 作
# 1,基础查询 GET demotest/_search { "query": { "match": { "sex": "man" } } } # 2,排序,sort GET demotest/_search { "query": { "match": { "sex": "man" } }, "sort": [ { "age": { "order": "desc" } } ] } # 3,分页查询,from:第几个,size:返回多少条 GET demotest/_search { "query": { "match": { "sex": "man" } }, "sort": [ { "age": { "order": "desc" } } ], "from": 0, "size": 2 } # 4,只返回指定的字段数据 GET demotest/_search { "query": { "match": { "sex": "man" } }, "_source": [ "name", "age" ] } # 5,bool查询,有must,must_not,should,filter # must是and条件查询,must_not是过滤,也是and条件 # should是or条件查询 # filter是过滤查询,也是and条件 # 区别:filter不计算评分,查询效率高;有缓存 GET demotest/_search { "query": { "bool": { "must": [ { "match": { "age": "36" } }, { "match": { "sex": "man" } } ] } } } # 6,term 查询是直接通过倒排索引指定的词条进行精确查找的 GET demotest/_search { "query": { "term": { "sex": "man" } } }
关于分词:
term:直接查询精确的
match:会使用分词器解析
两个类型 text keyword
text:可以被分词器解析
keyword:不被分词器解析,以完整的词存储
如果字段类型是text,那么可以使用match,根据分词器解析来查询到数据。但是要完全匹配一个字段的值,则可能会查不到。
如果字段类型是keyword,那么可以使用term来精确查找。因为keyword不分词,以完整词存储。
因此更多实际场景,有些字段的类型会是text和keyword两者都具备,这是可以的。
字段类型设置如下图:
text类型的:
比如desc字段,一般使用match查询匹配,类似模糊搜索。若是使用term精确查询,则可能会差不到。
keyword类型的:
比如sex字段,term和match都可以,但值要和数据库已有的准确匹配到才能匹配出来。
text和keyword类型都具备的:
比如name字段,这时候如果要模糊匹配,则使用match查找,若要精确匹配name字段的值,则使用name.keyword当字段查询。
GET demotest5/_search { "query": { "term": { "name.keyword": "刘备" } } }
这个其实理解倒排索引原理就很容易知道这两个类型的意思了。
高亮显示:highlight
GET demotest/_search { "query": { "match": { "like": "羽毛球" } }, "highlight": { "pre_tags": "", "post_tags": "
", "fields": { "like": {} } } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)