阅读 89

Elasticsearch检索

关于Elasticsearch增删改查请参考:https://www.jianshu.com/p/845db4615f96,本文中用到的测试数据,也来自这篇文章最后的“批量操作”,测试工具使用Kibana。

1、Search API

1.1、URI+检索参数

通过REST request uri 发送搜索参数
GET:发送GET请求进行检索;
bank:指定bank索引;
_search:固定写法,“?”后面跟的就是检索条件;
q=*:查询所有;
sort=account_number:asc:按照account_number升序排序。

GET bank/_search?q=*&sort=account_number:asc
es1.jpg
1.2、URI+请求体
GET /bank/_search
{
  //匹配所有数据
  "query": { "match_all": {} },
  //排序规则
  "sort": [
    //按照account_number升序排列
    { "account_number": "asc" }
  ]
}
es2.jpg

2、Query DSL

Query DSL官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
Elasticsearch提供了一个可以执行查询的Json风格的DSL。这个被称为Query DSL,该查询语言非常全面。
一个查询语句的典型结构

QUERY_NAME:{
   ARGUMENT:VALUE,
   ARGUMENT:VALUE,...
}

如果针对于某个字段,那么它的结构如下:

{
  QUERY_NAME:{
     FIELD_NAME:{
       ARGUMENT:VALUE,
       ARGUMENT:VALUE,...
      }   
   }
}
2.1、简单示例
GET bank/_search
{
  //定义查询条件
  "query": {
    "match_all": {}
  },
  //从第0条数据开始
  "from": 0,
  //返回5条数据
  "size": 5,
  "sort": [
    {
      "account_number": {
        "order": "desc"
      }
    }
  ]
}
es3.jpg
2.2、返回部分字段

若只需返回部分字段,添加_source字段

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "from": 0,
  "size": 5,
  "sort": [
    {
      "account_number": {
        "order": "desc"
      }
    }
  ],
  "_source": ["balance","firstname"]
}
es4.jpg
2.3、match匹配查询

基本类型(非字符串),精确控制

GET bank/_search
{
  "query": {
    "match": {
      "account_number": 944
    }
  }
}
es5.jpg

字符串,全文检索

GET bank/_search
{
  "query": {
    "match": {
      "address": "Laurel"
    }
  }
}
es6.jpg
2.4、match_phrase 短语匹配

将需要匹配的值当成一整个单词(不分词)进行检索

GET bank/_search
{
  "query": {
    "match_phrase": {
      "address": "Laurel Avenue"
    }
  }
}
es7.jpg
2.5、 multi_math 多字段匹配

state或者address中包含mill,并且在查询过程中,会对于查询条件进行分词。

GET bank/_search
{
  "query": {
    "multi_match": {
      "query": "mill",
      "fields": [
        "state",
        "address"
      ]
    }
  }
}
es8.jpg
2.6、bool 复合查询

复合语句可以合并,任何其他查询语句,包括复合语句。这也就意味着,复合语句之间可以互相嵌套,可以表达非常复杂的逻辑。

must:必须达到must所列举的所有条件。
实例:查询gender=m,并且address=mill的数据

GET bank/_search
{
   "query":{
        "bool":{
             "must":[
                {"match":{"address":"mill"}},
                {"match":{"gender":"M"}}
             ]
         }
    }
}

must_not:必须不匹配must_not所列举的所有条件。
实例:查询gender=m,并且address=mill的数据,但是age不等于38的

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "gender": "M"
          }
        },
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "38"
          }
        }
      ]
    }
  }

should:应该满足should所列举的条件。不满足should条件的,也可以被检索出来;满足should条件的,_score值会更大。
实例:在上面的基础上,匹配lastName应该等于Wallace的数据

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "gender": "M"
          }
        },
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "must_not": [
        {
          "match": {
            "age": "18"
          }
        }
      ],
      "should": [
        {
          "match": {
            "lastname": "Wallace"
          }
        }
      ]
    }
  }
}
2.7、filter 结果过滤

并不是所有的查询都需要产生相关性得分,特别是那些仅用于filtering过滤的文档。为了不计算分数,elasticsearch会自动检查场景并且优化查询的执行。

GET bank/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "address": "mill"
          }
        }
      ],
      "filter": {
        "range": {
          "balance": {
            "gte": "10000",
            "lte": "20000"
          }
        }
      }
    }
  }
}

es9.jpg

在boolean查询中,must, should 和must_not 元素都被称为查询子句 。 文档是否符合每个“must”或“should”子句中的标准,决定了文档的“相关性得分”。 得分越高,文档越符合您的搜索条件。 默认情况下,Elasticsearch返回根据这些相关性得分排序的文档。

“must_not”子句中的条件被视为“过滤器”。它影响文档是否包含在结果中,但不贡献相关性得分。

2.8、term

和match一样。匹配某个属性的值。全文检索字段用match,其他非text字段匹配用term。例如address、email这样的text字段用match,而age、balance这样的字段用term。

避免对文本字段使用“term”查询,默认情况下,Elasticsearch作为[analysis]的一部分更改’ text '字段的值。
这使得为“text”字段值寻找精确匹配变得困难。
GET bank/_search
{
  "query": {
    "term": {
      "age": 36
    }
  }
}
es10.jpg
2.9、Aggregation 执行聚合

聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于SQL Group by和SQL聚合函数。在elasticsearch中,执行搜索返回this(命中结果),并且同时返回聚合结果,把以响应中的所有hits(命中结果)分隔开的能力。这是非常强大且有效的,你可以执行查询和多个聚合,并且在一次使用中得到各自的(任何一个的)返回结果,使用一次简洁和简化的API来避免网络往返。

聚合语法如下:

"aggs":{
    "aggs_name这次聚合的名字,方便展示在结果集中":{
        "AGG_TYPE聚合的类型(avg,term,terms)":{}
     }
},

示例1:搜索address中包含mill的所有人的年龄分布以及平均年龄,但不显示这些人的详情。

GET /bank/_search
{
  "query": {
    "match": {
      "address": "mill"
    }
  },
  "size": 0,
  "aggs": {
    "age_term": {
      "terms": {
        "field": "age",
        "size": 100
      }
    },
    "age_avg":{
      "avg": {
        "field": "age"
      }
    }
  }
}

执行结果:


es11.jpg

示例2:按照年龄聚合,并且求这些年龄段的这些人的平均余额。

GET /bank/_search
{
  "query": {
    "match_all": {}
  },
  "size": 0,
  "aggs": {
    "age_term": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "avg_balance": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  }
}

执行结果:


es12.jpg

示例3:查出所有年龄分布,并且这些年龄段中M的平均余额和F的平均余额以及这个年龄段的总体平均余额

GET bank/_search
{
  "query": {
    "match_all": {}
  },
  "aggs": {
    "ageAgg": {
      "terms": {
        "field": "age",
        "size": 100
      },
      "aggs": {
        "genderAgg": {
          "terms": {
            "field": "gender.keyword"
          },
          "aggs": {
            "balanceAvg": {
              "avg": {
                "field": "balance"
              }
            }
          }
        },
        "ageBalanceAvg": {
          "avg": {
            "field": "balance"
          }
        }
      }
    }
  },
  "size": 0
}

执行结果:


es13.jpg

作者:LJessie

原文链接:https://www.jianshu.com/p/6b58dcac4fc8

文章分类
后端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐