Elasticsearch学习笔记-结构化搜索

97 阅读1分钟

1、精确值查找

当进行精确值查找时, 会使用过滤器(filters)。它执行速度非常快,不会计算相关度(直接跳过了整个评分阶段)而且很容易被缓存。
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
    "query": {
        "trem": {
            "user_id": 100
        }
    },
    "_source": ["user_id", "user_name"] #指定返回字段
}'
当查找一个精确值的时候,如果不希望对查询进行评分计算,只希望对文档进行包括或排除的计算,可以使用 constant_score 查询以非评分模式来执行 term 查询并以一作为统一评分。
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
    "query" : {
        "constant_score" : { #用 constant_score 将 term 查询转化成为过滤器
            "filter" : { #查询置于 filter 语句内不进行评分或相关度的计算
                "term" : {
                    "user_id": 100
                }
            }
        }
    }
}'

2、组合过滤器

一个 bool 过滤器由三部分组成:
{
   "bool" : {
      "must":  [], #所有的语句都必须(must) 匹配,与 AND 等价。
      "should": [], #至少有一个语句要匹配,与 OR 等价。
      "must_not": [] #所有的语句都不能(must not) 匹配,与 NOT 等价。
   }
}

#例1
SELECT user_name FROM users WHERE (age = 20 OR country = "china") AND (age != 30)
用Elasticsearch表示
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
   "query" : {
      "filtered" : { #filtered 查询将所有的东西包起来
         "filter" : {
            "bool" : {
              "should" : [
                 { "term" : {"age" : 20}}, 
                 { "term" : {"country" : "china"}} 
              ],
              "must_not" : {
                 "term" : {"age" : 30} 
              }
           }
         }
      }
   }
}'

#例2
SELECT user_name FROM users WHERE age = 20 OR (age = 30 AND country = "china" )
用Elasticsearch表示
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "bool" : {
              "should" : [
                { "term" : {"age" : 20}}, 
                { "bool" : { 
                  "must" : [
                    { "term" : {"age" : 30}}, 
                    { "term" : {"country" : "china"}} 
                  ]
                }}
              ]
           }
         }
      }
   }
}'

3、查找多个精确值

#使用terms查询
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
    "query": {
        "trems": {
            "user_id": [100,101]
        }
    },
    "_source": ["user_id", "user_name"] #指定返回字段
}'

term 和 terms 是 包含(contains) 操作,而非 等值(equals)。
比如 term(词项)过滤器 { "term" : { "tags" : "search" } } ,它会与以下两个文档同时匹配:
{ "tags" : ["search"] }
{ "tags" : ["search", "open_source"] } 

如果一定期望得到整个字段完全相等,最好的方式是增加并索引另一个字段, 这个字段用以存储该字段包含词项的数量:
{ "tags" : ["search"], "tag_count" : 1 }
{ "tags" : ["search", "open_source"], "tag_count" : 2 }
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
    "query": {
        "constant_score" : {
            "filter" : {
                 "bool" : {
                    "must" : [
                        { "term" : { "tags" : "search" } }, 
                        { "term" : { "tag_count" : 1 } } 
                    ]
                }
            }
        }
    }
}'

4、范围查找

range 查询可同时提供包含(inclusive)和不包含(exclusive)这两种范围表达式,可供组合的选项:
gt: > 大于(greater than)
lt: < 小于(less than)
gte: >= 大于或等于(greater than or equal to)
lte: <= 小于或等于(less than or equal to)

#例
SELECT user_name FROM users WHERE  user_id BETWEEN 666 AND 6666
用Elasticsearch表示
$ curl -XGET 'http://localhost:9200/trade/share/_search' -d '
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "range" : {
                    "user_id" : {
                       "gte" : 666,
                       "lte"  : 6666
                    }
                }
            }
        }
    }
}'

5、处理Null值

null, [](空数组) 和 [null] 所有这些都是等价的,它们无法存于倒排索引中。

#例1
SELECT user_name FROM users WHERE user_name IS NOT NULL
用Elasticsearch表示
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "exists" : { "field" : "user_name" }
            }
        }
    }
}

#例2
SELECT user_name FROM users WHERE user_name IS NULL
用Elasticsearch表示
{
    "query" : {
        "constant_score" : {
            "filter": {
                "missing" : { "field" : "user_name" }
            }
        }
    }
}