当前位置 > it书童 > elk > 正文
推荐小册
java高效编程
怎样更高效地用 java 编程

juc并发工具库
java并发编程工具库

设计模式
设计模式

jvm调优
jvm调优

rabbitmq实战
rabbitmq实战

redis实战
redis实战

Keepavlied高可用集群
Keepavlied高可用集群

nginx入门到实战
nginx入门到实战

java调试
java调试中遇到的各种坑

java输入输出流
java输入输出流

Elasticsearch 结构化查询

elk it书童 2019-10-04 10:55:27 0赞 0踩 607阅读 0评论

term查询

term主要用于精确匹配哪些值,比如数字,日期,布尔值或 not_analyzed的字符串(未经分析的文本数据类型):

    { "term": { "age":    26           }}
    { "term": { "date":   "2014-09-01" }}
    { "term": { "public": true         }}
    { "term": { "tag":    "full_text"  }}

示例:

# term 查询
POST /heros/_search
{
  "query": {
    "term": {
      "age": 22
    }
  }
}

# 结果
{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qjYKOW0B3p3gGxF6OLab",
        "_score" : 1.0,
        "_source" : {
          "name" : "段誉",
          "gender" : "男",
          "skill" : "六脉神剑",
          "age" : 22
        }
      }
    ]
  }
}

terms查询

termsterm 有点类似,但 terms 允许指定多个匹配条件。 如果某个字段指定了多个值,那么文档需要一起去做匹配:

{
    "terms": {
        "tag": [ "search", "full_text", "nosql" ]
        }
}

示例:

# terms 查询
POST /heros/_search
{
  "query": {
    "terms": {
      "age": [30, 52]
    }
  }
}

# 结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qzYKOW0B3p3gGxF6T7bF",
        "_score" : 1.0,
        "_source" : {
          "name" : "萧峰",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 30
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qTbyOG0B3p3gGxF6LrY4",
        "_score" : 1.0,
        "_source" : {
          "name" : "郭靖",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 52
        }
      }
    ]
  }
}

range查询

range过滤允许我们按照指定范围查找一批数据:

{
    "range": {
        "age": {
            "gte":  20,
            "lt":   30
        }
    }
}

范围操作符包含:

gt :: 大于

gte:: 大于等于

lt :: 小于

lte:: 小于等于

示例:

# rang 查询
POST /heros/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 20,
        "lte": 30
      }
    }
  }
}

# 结果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 2,
    "successful" : 2,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qjYKOW0B3p3gGxF6OLab",
        "_score" : 1.0,
        "_source" : {
          "name" : "段誉",
          "gender" : "男",
          "skill" : "六脉神剑",
          "age" : 22
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "qzYKOW0B3p3gGxF6T7bF",
        "_score" : 1.0,
        "_source" : {
          "name" : "萧峰",
          "gender" : "男",
          "skill" : "降龙十八掌",
          "age" : 30
        }
      },
      {
        "_index" : "heros",
        "_type" : "_doc",
        "_id" : "rDYKOW0B3p3gGxF6WrYB",
        "_score" : 1.0,
        "_source" : {
          "name" : "小龙女",
          "gender" : "女",
          "skill" : "玉女心经",
          "age" : 28
        }
      }
    ]
  }
}

exists 查询

exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,类似于SQL语句中的IS_NULL条件

{
    "exists":   {
        "field":    "title"
    }
}

这两个查询只是针对已经查出一批数据来,但是想区分出某个字段是否存在的时候使用。

示例:

# exists 查询 应该模拟多一些数据,文档结构不一致,方便测试
POST /heros/_search
{
  "query": {
    "exists": {
      "field": "age"
    }
  }
}

match查询

match查询是一个标准查询,不管你需要全文本查询还是精确查询基本上都要用到它。

如果你使用 match 查询一个全文本字段,它会在真正查询之前用分析器先分析match一下查询字符:

{
    "match": {
        "tweet": "About Search"
    }
}

如果用match下指定了一个确切值,在遇到数字,日期,布尔值或者not_analyzed 的字符串时,它将为你搜索你给定的值:

{ "match": { "age":    26           }}
{ "match": { "date":   "2014-09-01" }}
{ "match": { "public": true         }}
{ "match": { "tag":    "full_text"  }}

bool查询

bool 查询可以用来合并多个条件查询结果的布尔逻辑,它包含一下操作符:

must :: 多个查询条件的完全匹配,相当于 and

must_not :: 多个查询条件的相反匹配,相当于 not

should :: 至少有一个查询条件匹配, 相当于 or

这些参数可以分别继承一个查询条件或者一个查询条件的数组:

{
    "bool": {
        "must":     { "term": { "folder": "inbox" }},
        "must_not": { "term": { "tag":    "spam"  }},
        "should": [
          { "term": { "starred": true   }},
          { "term": { "unread":  true   }}
        ]
    }
}

过滤查询

前面讲过结构化查询,Elasticsearch也支持过滤查询,如term、range、match等。

示例:查询年龄为20岁的用户。

POST /itcast/person/_search
{
    "query": {
        "bool": {
            "filter": {
                "term": {
                    "age": 20
                }
            }
        }
    }
}

查询和过滤的对比

  • 一条过滤语句会询问每个文档的字段值是否包含着特定值。
  • 查询语句会询问每个文档的字段值与特定值的匹配程度如何。 一条查询语句会计算每个文档与查询语句的相关性,会给出一个相关性评分 _score,并且 按照相关性对匹配到的文档进行排序。 这种评分方式非常适用于一个没有完全配置结果的全文本搜索。
  • 一个简单的文档列表,快速匹配运算并存入内存是十分方便的, 每个文档仅需要1个字节。这些缓存的过滤结果集与后续请求的结合使用是非常高效的。
  • 查询语句不仅要查找相匹配的文档,还需要计算每个文档的相关性,所以一般来说查询语句要比 过滤语句更耗时,并且查询结果也不可缓存。

建议:

做精确匹配搜索时,最好用过滤语句,因为过滤语句可以缓存数据。

关于我
一个文科出身的程序员,追求做个有趣的人,传播有价值的知识,微信公众号主要分享读书思考心得,不会有代码类文章,非程序员的同学请放心订阅
转载须注明出处:https://www.itshutong.com/articles/71/elastic-search-structured-query