ES高级查询语法
1、analyze分词器
//新建索引
PUT /movie/_doc/1
{
"name":"Eating an apple a day & keeps the doctor away"
}
GET /movie/_search
{
"query": {
"match": {
"name": "Eat"
}
}
}
假如我们这样查询的话,结果就会显示一个空
我们使用分词器查看分词状态
可以发现分出了 eating an apple a
day keeps the docter away
anayle:分析=分词的过程:
字符过滤器-》字符处理-》分词过滤(分词转换)
因为没有指定分词器,所有默认标准分词器:standard
当我们指定English分词器时发生了变化
english anayle:分析=分词的过程:
字符过滤器(过滤特殊符号外加量词,the等等)-》字符处理-》分词过滤(分词转换,词干转换)
此时我们get的时候就可以搜索到
2、Tmdb实例
类型
- Text:被分析索引的字符串类型
- keyword:不能被分析只能被精确匹配的字符串类型
- Date:日期类型,可以配合format一起使用
- 数字类型:long,integer,short,double等
- Boolean:true false
- Array:“one”,“two”
- Object:json嵌套
- Ip类型
- Geo_point:地理位置
查询
1、使用match查询(text会被分词器)
按照字段上的定义的分词分析后去索引内查询
GET /movie/_analyze
{
"field":"title",
"text":"steve zissou"
}
2、使用term查询(相当于精确查询)
不进行分词的分析,直接去索引内查询
GET /movie/_analyze
{
"query"{
"term":{"title":"steve jobs"}
}
}
3、分词后的and和or的逻辑
match分词后是默认or的关系
只要存在被分词后的任意一个
即可以满足对应要求
改成and
GET /movie/_search
{
"query":{
"match":{
"title":{
"query":"basketball with cartoom aliens",
"operator":"and"
}
}
}
}
但or可能会匹配出一些不需要的,
所以我们可以优化or查询
最小词匹配项
GET /movie/_search
{
"query":{
"match":{
"title":{
"query":"basketball with cartoom aliens",
"operator":"or",
"minimum_should_match":2
}
}
}
}
加上这个意味着至少命中两个
4、短语查询
GET /movie/_search
{
"query":{
"match_phrase":{"title":"steve zissou"}
}
}
就不会做分词了
5、多字段查询
GET /movie/_search
{
"query":{
"multi_match":{
"query":"basketball with cartoom aliens",
"fields":["title","overview"]
}
}
}
这样写也是or的查询逻辑
每次查询都会出现_score
我们来看下打分规则
TF IDF TFNORM
- TF:token frequency ,basketball这样一个分词在document字段(待搜索的字段)中出现的次数
- IDF:inverse document frequency,逆文档频率,代表basketball这样一个分词在整个文档中出现的频率,取反
- TFNORM:token frequency nomalized 词频归一化 (这个词在这个文档中出现的频率)
BM25:解决词频问题
总体的分就是各个value的乘积
多字段查询优化
GET /movie/_search
{
"explain":true,
"query":{
"multi_match"{
"query":"basketball with cartoom aliens",
"fields":["title","overview"]
}
}
}
这样查询可能会导致文中出现目标字段比标题出现目标字段评分更高
优化:
GET /movie/_search
{
"query":{
"explain":true,
"multi_match"{
"query":"basketball with cartoom aliens",
"fields":["title^10","overview"]
}
}
}
意味着命中title比命中文章高十倍
GET /movie/_search
{
"query":{
"explain":true,
"multi_match"{
"query":"basketball with cartoom aliens",
"fields":["title^10","overview"],
“tie_breaker”:0.3
}
}
}
这样得分就是最大命中数量和其他命中目标*0.3的总和
bool查询
must:必须都为true
must not:必须都是false
should:其中只有一个为true即可
为true的越多得分越高
GET /movie/_search
{
"explain":true,
"query":{
"bool":{
"should":[
{"match":{"title":basketball with cartoom aliens"}},
{"match":{"overview":basketball with cartoom aliens"}}
]
}
}
}
不同的multi_query其实是有不同的type
best_fields:默认的得分方式,取得最高分数作为对应文档的对应分数,“最匹配模式”
GET /movie/_search
{
"query":{
"explain":true,
"multi_match"{
"query":"basketball with cartoom aliens",
"fields":["title","overview"],
"type":"best_fields"
}
}
}
和如下同理
GET /movie/_search
{
"explain":true,
"query":{
"dis_max":{
"queries":[
{"match":{"title":basketball with cartoom aliens"}},
{"match":{"overview":basketball with cartoom aliens"}}
]
}
}
}
GET /movie/_validate/query?explain
{
"query":{
"multi_match":{
"query":"basketball with cartoom aliens",
"fields":["title","overview"],
"type":"best_fields"
}
}
}
most_fields:考虑绝大多数(所有的)文档的字段得分相加,获得我们想要的结果
GET /movie/_validate/query?explain
{
"query":{
"multi_match":{
"query":"basketball with cartoom aliens",
"fields":["title","overview"],
"type":"most_fields"
}
}
}
#cross_fields:以分词为单位计算栏位的总分
适用于词导向的匹配
```java
GET /movie/_validate/query?explain
{
"query":{
"multi_match":{
"query":"Steve job",
"fields":["title","overview"],
"type":"most_fields"
}
}
}
排序和过滤
query string
方便利用 and or not
GET /movie/_search
{
"query":{
"query_string":{
"fields":["title"],
"query":"steve AND jobs"
}
}
}
filter过滤查询
单条件过滤
GET /movie/_search
{
"query":{
"bool"{
"filter":{
"term":{"title":"steve"}
}
}
}
}
这样所有的打分都是0,因为过滤没有排序的能力
GET /movie/_search
{
"query":{
"bool"{
"filter":[
{"term":{"title":"steve"}},
{"term":{"cast.name":"gaspard"}},
{"range":{"release_date":{"lte":"2015/01/01"}}},
{"range":{"popularity":{"gte":"25"}}}
]
}
}
}
时间小于等于2015.1.1
对应的评分大于25分
带match打分的filter
GET /movie/_search
{
"query":{
"bool"{
"must":[
{"should":{"title":"life"}}
],
"filter":[
{"term":{"title":"steve"}},
{"term":{"cast.name":"gaspard"}},
{"range":{"release_date":{"lte":"2015/01/01"}}},
{"range":{"popularity":{"gte":"25"}}}
]
}
}
}
查全率和查准率
- 查全率:正确的结果有n个,查询出来正确的有m m/n
- 查准率:查出的n个文档有m个正确 m/n
- 两者不可兼得,但可以调整排序
functionscore
GET /movie/_search
{
"query":{
"function_score":{
"query":{
"multi_match":{
"query":"steve job",
"fields":["title","overview"],
"operator":"or",
"type":"most_fields"
}
},
"functions":[
{
"field_value_factor":{
"field":"popularity",
//对应要调整的字段
"modifier":"log2p",
"factor":10
}
]
}
}
}