赞
踩
文档过滤filter
过滤的效果其实有点像条件搜索,不过条件搜索会考虑相关度分数和考虑分词,而过滤是不考虑这些的,过滤对相关度没有影响。过滤一般用于结构化的数据上,也就是通常不用于使用了分词的数据上,通常都会用在数值类型和日期类型的数据上。
在搜索的时候,如果你不希望要搜索的条件会影响到相关度,那么就把它放在过滤中,如果希望影响相关度,那么就放在条件搜索中。
使用过滤时,由于不考虑相关度,所以score固定为1。
文档的过滤filter里面主要有五种字段,range,term,terms,exist,missing。range用于字段数据比较大小;term主要用于比较字符类型的和数值类型的数据是否相等;terms是term的复数版,里面可以有多个用于比较相等的值;exist和missing用于判断文档中是否包含指定字段或没有某个字段(仅适用于2.0+版本,目前已经移除)
// range,gte是不小于,lte是不大于,eq是等于,gt是大于,lt是小于
GET / index/type/_search
{
"query": {
"range": {
"字段名": {
"gte": 比较值
[,"lte": 比较值]
}
}
}
}
GET /douban/book/_search
{
"query": {
"range": {
"book_pages": {
"gte": 352,
"lt":400
}
}
}
}
// term用于匹配字符串和数值型类型的数据(解决了range中没有eq的问题),但不能直接用于分词的字段。
//【这个并没有那么简单,会后续再讲,直接匹配一些会分词的字段时,会匹配失败,
//因为这时候这个字段拿来匹配的都是散乱的值,不是完整的原本的字段数据,所以下面用了不分词的数值型的字段来演示】
GET /douban/book/_search
{
"query": {
"term": {
"字段": "搜索值"
}
}
}
GET /douban/book/_search
{
"query": {
"term": {
"book_pages": 352
}
}
}
//terms
GET /douban/book/_search
{
"query": {
"terms": {
"字段": ["搜索值1","搜索值2"]
}
}
}
GET /douban/book/_search
{
"query": {
"terms": {
"book_pages": [
"352",
"400"
]
}
}
}
term的问题:
首先,提一下的是,在搜索的时候,你并不直接面向原始文档数据,而是面向倒排索引,这意思是什么呢?比如你要进行全文搜索,那么你的搜索值并不是与数据文件比对的,而是与倒排索引匹配的,也就是在我们与数据文件之间有一个专门用于搜索的层次。
对于match和match_all,这些都是全文搜索,就不说了,直接就是通过索引词在索引文件中找到对应的文档;比较不同的是match_phrase这个会匹配一段词的搜索,他是怎么查询的呢?他实际上也会去查索引文件中包括了搜索值中所有词并且词的在文档中的位置顺序也一致的记录,所以这个短语匹配其实也是通过倒排索引来搜索的。
而倒排索引中其实包含了所有字段的标识,对于分词的字段,会存储索引词;对于不分词的,会存储整个数据。【对于分词的字段可以加一个keyword来保留完整的数据,这个后面再讲。】
而term的搜索主要面向不分词的数据,所以无法直接用于分词的字段,除非加keyword。
filter与bool
filter也可以用于多条件拼接。例如:
GET /douban/book/_search
{
"query": {
"bool": {
"must": [
{
"match":{
"book_name":"Story"
}
},
{
"range": {
"book_pages": {
"lte":300
}
}
}
]
}
}
}
GET /douban/book/_search
{
"query": {
"bool": {
"must": [
{
"match":{
"book_name":"Story"
}
},
{
"range": {
"book_pages": {
"lte":300
}
}
},
{
"term": {
"publish_date": "1994-02-01"
}
}
]
}
}
}
constant_score
GET /douban/book/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"book_pages": {
"gte": 352,
"lt": 400
}
}
}
}
}
}
// boost设置filter提供的相关度score值
GET /douban/book/_search
{
"query": {
"constant_score": {
"filter": {
"range": {
"book_pages": {
"gte": 352,
"lt": 400
}
}
},
"boost": 1.2
}
}
}
对于过滤,elasticsearch会临时缓存它的结果,以便可能下次仍需使用它。因为过滤是不关心相关度的
小结:
这节介绍了不影响相关度的搜索–过滤,过滤通常用于过滤结构化数据,也就是那些不分词的数据,其中range用于数值范围过滤,term用于字符类型的数据或数值类型的数据的值是否相等,terms是term的复数版。过滤也支持bool拼接多个条件。过滤提供的相关度分数是一个常数,默认是1。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。