前言
ES权威指南
1.Java交互
1.1 节点客户端(Node client)
节点客户端作为一个非数据节点加入到本地集群中。换句话说,它本身不保存任何数据,但是它知道数据在集群中的哪个节点中,并且可以把请求转发到正确的节点。
1.2 传输客户端(Transport client)
轻量级的传输客户端可以可以将请求发送到远程集群。它本身不加入集群,但是它可以将请求转发到集群中的一个节点上。
1.3 spring-data-elasticsearch
与Spring框架整合,可以使用java链式风格构建语句或者使用Json请求,构建index可以使用注解方式或模版方式。
2.REST API
3.深入搜索
3.1 term/terms 包含搜索 : 处理数字(numbers)、布尔值(Booleans)、日期(dates)、文本(text)
-{ "term" : { "price" : 20 }}
-{"terms" : { "price" : [20, 30] }}
3.2 bool过滤器 : must、should、must_not
-{ "bool" : { "must" : [], "should" : [], "must_not" : [] }}
-{ "query": { "bool": { "should": [ { "match": { "title": "brown" }}, { "match": { "title": "fox" }}, { "match": { "title": "dog" }} ], "minimum_should_match": 2 } }} //minimum_should_match控制should中多少条件需要被满足,可以是数字可以是百分比,百分比会自动截断
-{"should": [ { "match": { "content": { "query": "Elasticsearch", "boost": 3 } }}, { "match": { "content": { "query": "Lucene", "boost": 2 } }} ]} //boost用来控制条件的权重
3.3 range 范围搜索 :
在倒排索引中的词项就是采取字典顺序(lexicographically)排列的,这也是字符串范围可以使用这个顺序来确定的原因
-"range" :{ "price" : { "gte" : 20, "lte" : 40 }}
-"range" : { "title" : { "gte" : "a", "lt" : "b" }}
3.4 exists、missing 处理null
-{ "exists" : { "field" : "tags" } } //tags字段不为null的
-{ "missing" : { "field" : "tags" } } //tags字段为null的,es5.x废弃
判断一个对象是否为null时,相当于做一个bool判断
-{ "name" : { "first" : "John", "last" : "Smith" }}
-{ "exists" : { "field" : "name" }}
-{ "bool": { "should": [ { "exists": { "field": "name.first" }}, { "exists": { "field": "name.last" }} ] }}
3.5 match 高层查询
-{"match": { "title": "QUICK!" }} //单词查询
-{"match": { "title": { "query": "BROWN DOG!"} }} //多词查询默认是包含关系,即brown/dog
-{"match": { "title": { "query": "BROWN DOG!", "operator": "and" }}} // 多词查询精确匹配
-{"match": { "title": { "query": "quick brown dog", "minimum_should_match": "75%" }}} // 控制匹配精度,这里会自动截断成66.66%,匹配包含2个词以上的文档
Elasticsearch 执行上面这个 match 查询的步骤是:
1) 检查字段类型。如果标题 title 字段是一个 string 类型( analyzed )已分析的全文字段,这意味着查询字符串本身也应该被分析。
2) 分析查询字符串。将查询的字符串 QUICK! 传入标准分析器中,输出的结果是单个项 quick 。因为只有一个单词项,所以 match 查询执行的是单个底层 term 查询。
3) 查找匹配文档。用 term 查询在倒排索引中查找 quick 然后获取一组包含该项的文档。
4) 为每个文档评分。用 term 查询计算每个文档相关度评分 _score ,这是种将词频(term frequency,即词 quick 在相关文档的 title 字段中出现的频率)和反向文档频率(inverse document frequency,即词 quick 在所有文档的 title 字段中出现的频率),以及字段的长度(即字段越短相关度越高)相结合的计算方式。
PS:Elasticsearch 的相似度算法被定义为检索词频率/反向文档频率,TF/IDF,包括以下内容:
1)检索词频率。检索词在该字段出现的频率,出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。
2)反向文档频率。每个检索词在索引中出现的频率,频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。
3)字段长度准则。字段的长度是多少,长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。
3.6 analyzer 分析器
1)查询自己定义的 analyzer ,否则
2)字段映射里定义的 search_analyzer ,否则
3)字段映射里定义的 analyzer ,否则
4)索引设置中名为 default_search 的分析器,默认为
5)索引设置中名为 default 的分析器,默认为
6)standard 标准分析器
3.7 dis_max 分离最大化查询:将任何与任一查询匹配的文档作为结果返回,但只将最佳匹配的评分作为查询的评分结果返回,比如针对如下文档
(1) { "title": "Quick
brownrabbits", "body": "Brownrabbits are commonly seen."}(2) { "title": "Keeping pets healthy", "body": "My quick
brownfoxeats rabbits on a regular basis."}
使用bool查询,(1)文档匹配中两个,两个评分相加然后除以子查询个数(这里为2),(2)文档匹配中一个,两个评分相加然后除以子查询个数(这里为2),所以(1)文档评分会高一点
{ "query": { "bool": { "should": [ { "match": { "title": "Brown fox" }}, { "match": { "body": "Brown fox" }} ] } }}
使用dis_max查询,(1)文档匹配中两个,两个评分相加然后除以子查询个数(这里为2),(2)文档匹配中一个,只有该评分参与最终评分的计算,所以(2)文档评分会高一点
{ "query": { "dis_max": { "queries": [ { "match": { "title": "Brown fox" }}, { "match": { "body": "Brown fox" }} ] } }}
PS:tie_breaker(0到1之间的数),提供了一种 dis_max 和 bool 之间的折中选择,它的评分方式如下:(1) 获得最佳匹配语句的评分 _score;(2)将其他匹配语句的评分结果与 tie_breaker 相乘;(3)对以上评分求和并规范化。
{ "query": { "dis_max": { "queries": [ { "match": { "title": "Quick pets" }}, { "match": { "body": "Quick pets" }} ], "tie_breaker": 0.3 } }}
3.8 multi_match 多字段查询,支持正则表达式(可以使用 ^ 字符语法为单个字段提升权重)
{ "multi_match": { "query": "Quick brown fox", "fields": [ "*_title", "chapter_title^2" ] } }
使用"type": "most_fields"将所有匹配字段的评分合并起来
{ "query": { "multi_match": { "query": "jumping rabbits", "type": "most_fields", "fields": [ "title", "title.std" ] } }}
3.9 copy_to 自定义 _all 字段解决跨字段查询问题
{ "mappings": { "person": { "properties": { "first_name": { "type": "string", "copy_to": "full_name" }, "last_name": { "type": "string", "copy_to": "full_name" }, "full_name": { "type": "string" } } } }}
3.10 sort 排序
{"sort": {"date": {"order":"desc"}}}
{"sort": [ { "date": { "order": "desc" }}, { "_score": { "order": "desc" }} ]} //多级排序
{"sort": { "dates": { "order": "asc", "mode": "min" }}} //使用min,avg,max,sum模式
对analyzed字段字符串进行强制排序会消耗大量内存,可以使用多值字段字符串进行排序
"tweet": {
"type": "string",
"analyzer": "english",
"fields": { "raw": { "type": "string", "index": "not_analyzed" } }
}
=>{"sort": "tweet.raw"}