• elasticsearch轻量搜索的那些事


    前言

    elasticsearch本身就是为搜索而生的组件,所以搜索才是它的重头戏。从今天我们就学习es的各种检索语法了,但是我大概看了下官方文档,发现他对于各种检索语法的解释比较少,虽然也有好多示例,但是都比较零散,很难让我们看清楚它的语法规则。因此,我们今天也不会有太多内容分享,但是我这边会花两天时间梳理相关规则,争取未来两天整理出它的语法规则。

    下面我们就先来看一些简单的检索规则。

    elastsearch搜索

    轻量搜索

    这个检索语法类似于我们传统数据库中不加条件的查询语句,他会查询megacorp索引下所有employee的数据,然会返回

    curl -X GET "localhost:9200/megacorp/employee/_search?pretty"
    

    返回结果如下:

    {
      "took" : 78,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 1,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "megacorp",
            "_type" : "employee",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "name" : "syske",
              "age" : 25,
              "about" : "I love to read book",
              "interests" : [
                "sports",
                "music"
              ]
            }
          }
        ]
      }
    }
    
    

    下面我们简单解释下搜索结果:

    • took:这个应该搜索耗时时间,单位一般应该是毫秒,在测试过程中我发现每次的返回结果都会都差异

    • timed_out:请求是否超时

    • _shards:分片,应该和存储有关,类似于传统数据存储中的分库分表,应该就是存储分割的单位。这里返回的是我们分片的汇总信息

    • _shards.total:总分片数

    • _shards.successful:这个应该表示的是搜索到结果的分片数

    • _shards.skipped:这个应该表示未搜索到数据的分片数

    • _shards.failed:那这个就表示搜索失败的分片数了

    • hits:这应该就是我们搜索到的结果

    • hits.total:主要存放返回结果汇总信息

    • hits.total.value:查询到的结果数量

    • hits.total.relation:查询结果的关系,eq表示相等(应该是equals的简写),那ne应该就表示不相等,目前没找到官方给的说明,网上也没有比较靠谱的解释。

    • hits.max_score:返回结果中score的最大值,这个score应该表示匹配度,因为没有文档,所以暂时只能推测

    • hits.hits:这个就是最终的搜索结果了,所有的匹配结果都会在这里面显示。这底下的数据也和我们get返回的结果很类似。

    • hits.hits._index:索引

    • hits.hits._type:数据类型

    • hits.hits._id:数据id

    • hits.hits._score:这个就是我们刚说的匹配度

    • hits.hits._source:最终的搜索结果

      根据关键字搜索

      相比于前面的那种查询全部,这种方式查询就比较灵活了,我们可以根据数据中的某个字段名进行查询,具体语法如下:

      索引/数据类型/_search?q=字段名:字段值
      

      下面是搜索样例:

      curl -X GET "localhost:9200/megacorp/employee/_search?q=name:syske&pretty"
      

      返回结果如下:

      {
        "took" : 6,
        "timed_out" : false,
        "_shards" : {
          "total" : 1,
          "successful" : 1,
          "skipped" : 0,
          "failed" : 0
        },
        "hits" : {
          "total" : {
            "value" : 1,
            "relation" : "eq"
          },
          "max_score" : 0.2876821,
          "hits" : [
            {
              "_index" : "megacorp",
              "_type" : "employee",
              "_id" : "1",
              "_score" : 0.2876821,
              "_source" : {
                "name" : "syske",
                "age" : 25,
                "about" : "I love to read book",
                "interests" : [
                  "sports",
                  "music"
                ]
              }
            }
          ]
        }
      }
      

      具体返回结果如下:

      查询不到结果时,返回结果如下:

      查询表达式搜索

      Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。

      领域特定语言DSL), 使用 JSON 构造了一个请求。

      查询语法也基本上和我们前面的查询一致,唯一的区别是,表达式搜索的时候,需要传一个json的表达式:

      curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
      {
          "query" : {
              "match" : {
                  "name" : "syske"
              }
          }
      }
      '
      

      返回结果:

      {
        "took" : 50,
        "timed_out" : false,
        "_shards" : {
          "total" : 1,
          "successful" : 1,
          "skipped" : 0,
          "failed" : 0
        },
        "hits" : {
          "total" : {
            "value" : 2,
            "relation" : "eq"
          },
          "max_score" : 0.18232156,
          "hits" : [
            {
              "_index" : "megacorp",
              "_type" : "employee",
              "_id" : "2",
              "_score" : 0.18232156,
              "_source" : {
                "name" : "syske",
                "age" : 18,
                "about" : "I love to read book",
                "interests" : [
                  "sports",
                  "music"
                ]
              }
            },
            {
              "_index" : "megacorp",
              "_type" : "employee",
              "_id" : "1",
              "_score" : 0.18232156,
              "_source" : {
                "name" : "syske",
                "age" : 15,
                "about" : "I love to read book",
                "interests" : [
                  "sports",
                  "music"
                ]
              }
            }
          ]
        }
      }
      

      关于表达式的写法,我们下面继续研究:

      curl -X GET "localhost:9200/megacorp/employee/_search?pretty" -H 'Content-Type: application/json' -d'
      {
          "query" : {
              "bool": {
                  "must": {
                      "match" : {
                          "name" : "syske" 
                      }
                  },
                  "filter": {
                      "range" : {
                          "age" : { "gt" : 15 } 
                      }
                  }
              }
          }
      }'
      

      表达式中的filter,其实就是对我们前面查出来的结果进行过滤。关于表达式的逻辑关系,我们先补充一点内容:

      • EQ 就是 EQUAL等于
      • NE就是 NOT EQUAL不等于
      • GT 就是 GREATER THAN大于 
      • LT 就是 LESS THAN小于
      • GE 就是 GREATER THAN OR EQUAL 大于等于
      • LE 就是 LESS THAN OR EQUAL 小于等于

      上面表达式最终查出的结果如下:

      {
        "took" : 18,
        "timed_out" : false,
        "_shards" : {
          "total" : 1,
          "successful" : 1,
          "skipped" : 0,
          "failed" : 0
        },
        "hits" : {
          "total" : {
            "value" : 1,
            "relation" : "eq"
          },
          "max_score" : 0.18232156,
          "hits" : [
            {
              "_index" : "megacorp",
              "_type" : "employee",
              "_id" : "2",
              "_score" : 0.18232156,
              "_source" : {
                "name" : "syske",
                "age" : 18,
                "about" : "I love to read book",
                "interests" : [
                  "sports",
                  "music"
                ]
              }
            }
          ]
        }
      }
      

      在我们的megacorp索引下,名字为syskeemployee数据有两条,年龄分别为1815,因为我们过滤条件为年龄大于15,所以查出的结果只有年龄为18的。

      注意:实际在测试的时候,发现range表达之只支持gtlt,其他都不支持。

    总结

    elasticsearch因为有自己特定的领域特定语言DSL),所以我们真正想要用好es,还是要学好DSL相关语法的,这也是我截止到目前都没有通过java去访问es的一个重要原因。学东西有时候是不能探快的,学好基础才是关键,只有学好了基础内容,后面上手才会更容易,毕竟java操作es也是建立在es的各种基础语法之上的。

  • 相关阅读:
    JS reduce方法的使用
    面试娱录
    sticky置顶功能影响了锚点定位
    postcss-px-to-viewport移动端自适应
    axios请求参数自动拼接到了地址那里
    ping 不通。无法访问目标主机
    JS前后台方法的相互调用
    SQL server2008 无法连接服务器
    Assembly.Load未能加载文件或程序集“”或它的某一个依赖项。系统找不到指定的文件
    JS判断IE和非IE
  • 原文地址:https://www.cnblogs.com/caoleiCoding/p/15195101.html
Copyright © 2020-2023  润新知