将一个field索引两次来解决字符串排序
如果对一个string field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了
通常解决方案是,将一个string field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序
PUT /website
{
"mappings":{
"article":{
"properties":{
"title":{
"type":"text", 第一次索引进行分词
"fields":{ 第二次索引不进行分词
"raw":{
"type":"string",
"index":"not_analyzed"
}
},
"fielddata":true 正排索引
},
"content":{
"type":"text"
},
"post_date":{
"type":"date"
},
"author_id":{
"type":"long"
}
}
}
}
}
GET /website/article/_search
{
"query":{
"match_all":{
}
},
"sort":[
{
"title.raw":{ //如果直接使用title的话是对分词之后的结果排序可能存在问题 title.raw 使用不分词的索引进行排序
"order":"desc"
}
}
]
}
相关度评分TF&IDF算法独家解密
1、算法介绍
relevance score算法,简单来说,就是计算出,一个索引中的文本,与搜索文本,他们之间的关联匹配程度
Elasticsearch使用的是 term frequency/inverse document frequency算法,简称为TF/IDF算法
Term frequency:搜索文本中的各个词条在field文本中出现了多少次,出现次数越多,就越相关
搜索请求:hello world
doc1:hello you, and world is very good
doc2:hello, how are you
Inverse document frequency:搜索文本中的各个词条在整个索引的所有文档中出现了多少次,出现的次数越多,就越不相关
搜索请求:hello world
doc1:hello, today is very good
doc2:hi world, how are you
比如说,在index中有1万条document,hello这个单词在所有的document中,一共出现了1000次;world这个单词在所有的document中,一共出现了100次
doc2更相关
Field-length norm:field长度,field越长,相关度越弱
搜索请求:hello world
doc1:{ "title": "hello article", "content": "babaaba 1万个单词" }
doc2:{ "title": "my article", "content": "blablabala 1万个单词,hi world" }
hello world在整个index中出现的次数是一样多的
doc1更相关,title field更短
GET /people/man/111/_explain
GET /people/man/_search?explain
{
"query":{
"match":{
"name":"ajax"
}
}
}