一个搜索请求过来,是怎样进行打分的呢
boolean model
首先一个搜索请求过来的时候,会先进行过滤,过滤出包含指定term的doc,这个过程就是boolean model
举个例子,查询的是hello world,首先会先过滤出来包含hello和包含world和包含hello world的数据,过滤出来的这些document是不会去打分数的.为了减少后续计算的document的数量,提升性能
TF/IDF算法
第二步进行TF/IDF计算,之前有详细说过这部分的计算,但是这两个是计算的单个term在doc里面的分数.
比如有两个document
doc1:java is my favourite programming language, hello world !!!
doc2:hello java, you are very good, oh hello world!!!
还是搜索hello world
先计算hello对于doc1的分数
TF(term frequency)算法:
找到hello在doc1中出现了几次,会根据出现的次数给个分数,一个term在一个doc中出现的次数越多,给的相关度评分就越高
IDF(inversed document frequency)算法:
找到hello在所有的doc中出现的次数,一个term在所有的doc中,出现的次数越多,评分越低.
然后是length norm,hello搜索的那个field的长度,filed长度越长,给的相关度评分越低,field长度越短,给的相关度评分越高.
最后,会将hello这个term对doc1的分数综合TF IDF length norm,计算出来一个综合的分数
计算world的方法同样的
上面我们可以看出计算的只是单个term对于doc的分数,但是最后需要给这个query对于doc的总的分数,就是第三步vector space model
vector space model
计算多个term对于一个doc的总分数
比如说上面的hello world,es会根据hello world在所有的doc中的评分情况,计算出一个总的 query vector(query向量)
比如说,hello这个term,给的基于所有doc的一个评分就是2,world这个term,给的基于所有doc的一个评分就是5,那么这个向量就是[2,5]
再举个例子,现在有3个doc,分别是
doc1:包含hello
doc2:包含world
doc3:包含hello,world
查询的还是hello world,会拿每个term计算出一个分数来,hello有一个分数,world有一个分数,再拿所有的term的分数组成一个doc vector
那么doc1就是[2,0],doc2是[0,5],doc3是[2,5] 把这几个分数画在一个坐标中就是:
然后会取每个doc vector对于query vector的弧度,给出每个doc对于多个term的总分数,弧度越大,分数越低,弧度越小,分数越高
如果term不止两个,是多个的话,就无法用图表示了,就是线性代数来计算