elasticsearch权威指南笔记2 - 简单使用

Posted ArcheWong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了elasticsearch权威指南笔记2 - 简单使用相关的知识,希望对你有一定的参考价值。

2. 使用

2.1 基本语法

如果你正在使用 Java,在代码中你可以使用 Elasticsearch 内置的两个客户端。所有其他语言可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信,你可以用你最喜爱的 web 客户端访问 Elasticsearch 。事实上,正如你所看到的,你甚至可以使用 curl 命令来和 Elasticsearch 交互。

注意

Elasticsearch 为以下语言提供了官方客户端 --Groovy、javascript、.NET、 php、 Perl、 Python 和 Ruby--还有很多社区提供的客户端和插件,所有这些都可以在 Elasticsearch Clients 中找到。

一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'

被 < > 标记的部件含义:

字段 含义
VERB 适当的 HTTP 方法 或 谓词 : GETPOSTPUTHEAD 或者 DELETE
PROTOCOL http 或者 https(如果你在 Elasticsearch 前面有一个https 代理)
HOST Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。
PORT 运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
PATH API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING 任意可选的查询字符串参数 (例如 ?pretty将格式化地输出 JSON 返回值,使其更容易阅读)
BODY 一个 JSON 格式的请求体 (如果请求需要的话)

例如,计算集群中文档的数量,我们可以用这个(完整模式):

curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}'

想要在返回结果中看到 HTTP 头信息,需要结合 `-i 参数来使用 curl 命令:

curl -i -XGET 'localhost:9200/'

缩写格式显示:

所谓的缩写格式就是省略请求中所有相同的部分,例如主机名、端口号以及 curl 命令本身。而不是像上面例子中显示的那样用一个完整的请求

GET /_count
{
    "query": {
        "match_all": {}
    }
}

2.2 理解:(官方实例:索引雇员文档)

一个 Elasticsearch 集群可以包含多个索引(类似于数据库),相应的每个索引可以包含多个类型。这些不同的类型存储着多个文档 ,每个文档又有多个属性 。

借助以下一条查询出的结果理解:

{
  "_index": "megacorp",
  "_type": "employee",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "first_name": "John",
    "last_name": "Smith",
    "age": 25,
    "about": "I love to go rock climbing",
    "interests": [
      "sports",
      "music"
    ]
  }
}

每个雇员索引一个文档,包含该雇员的所有信息。

每个文档都将是 employee 类型

该类型位于 索引 megacorp 内。

该索引保存在我们的 Elasticsearch 集群中。

2.2.1 插入数据

可以借助于kibana的console,浏览器打开地址:

http://xxx.xxx.xxx.xxx:5601/app/kibana#/dev_tools/console?_g=()

在console中输入,然后运行

PUT /megacorp/employee/1
{
    "first_name" : "John",
    "last_name" :  "Smith",
    "age" :        25,
    "about" :      "I love to go rock climbing",
    "interests": [ "sports", "music" ]
}

路径 /megacorp/employee/1 包含了三部分的信息:

  • megacorp :索引名称
  • employee :类型名称
  • 1 :特定雇员的ID
  • 2.2.2 检索文档

  1. 在bibana的console中输入运行

    GET /megacorp/employee/1

返回结果包含了文档的一些元数据,以及 _source 属性,内容是 John Smith 雇员的原始 JSON 文档:

{
  "_index": "megacorp",
  "_type": "employee",
  "_id": "1",
  "_version": 1,
  "found": true,
  "_source": {
    "first_name": "John",
    "last_name": "Smith",
    "age": 25,
    "about": "I love to go rock climbing",
    "interests": [
      "sports",
      "music"
    ]
  }
}
  1. 搜索所有雇员

    GET /megacorp/employee/_search

返回结果包括了所有三个文档,放在数组 hits 中。一个搜索默认返回十条结果

  1. 通过url参数来搜索

    GET /megacorp/employee/_search?q=last_name:Smith

  2. 使用查询表达式搜索

Query-string 搜索通过命令非常方便地进行临时性的即席搜索 ,但它有自身的局限性

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

GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}

可以看到上面不再使用query-srting参数,而是一个请求体。

  1. 更复杂的搜索
GET /megacorp/employee/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}

注意这里搜索last_name是smith的人,同时年龄大于30。注意下语法bool里面有must,filter类型,当然以后还会学到更多类型,这里先有个意识。

  1. 全文搜索
GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "about" : "rock climbing"
        }
    }
}
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.53484553,
    "hits": [
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "1",
        "_score": 0.53484553,
        "_source": {
          "first_name": "John",
          "last_name": "Smith",
          "age": 25,
          "about": "I love to go rock climbing",
          "interests": [
            "sports",
            "music"
          ]
        }
      },
      {
        "_index": "megacorp",
        "_type": "employee",
        "_id": "2",
        "_score": 0.26742277,
        "_source": {
          "first_name": "Jane",
          "last_name": "Smith",
          "age": 32,
          "about": "I like to collect rock albums",
          "interests": [
            "music"
          ]
        }
      }
    ]
  }
}

注意这里稍有不同,about字段中包含两个单词,搜索的结果并不是完全匹配,是根据单词去做了相关性匹配。

Elasticsearch 默认按照相关性得分排序,即每个文档跟查询的匹配程度。

Elasticsearch中的 相关性 概念非常重要,也是完全区别于传统关系型数据库的一个概念,数据库中的一条记录要么匹配要么不匹配。

  1. 短语搜索

上面如果一个短语包含多个单词,那岂不是不能精确查询了,当然不是,可以使用短语搜索。

GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    }
}

这样结果就是精确匹配了,仅匹配同时包含 “rock” 和 “climbing” ,并且 二者以短语 “rock climbing” 的形式紧挨着的结果

  1. 高亮搜索
GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}

结果中多了一个highlight部分

{
   ...
   "hits": {
      "total":      1,
      "max_score":  0.23013961,
      "hits": [
         {
            ...
            "_score":         0.23013961,
            "_source": {
               "first_name":  "John",
               "last_name":   "Smith",
               "age":         25,
               "about":       "I love to go rock climbing",
               "interests": [ "sports", "music" ]
            },
            "highlight": {
               "about": [
                  "I love to go <em>rock</em> <em>climbing</em>" 
               ]
            }
         }
      ]
   }
}
  1. 聚合

聚合类似于SQL中的GROUP_BY,但功能更强大

GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": { "field": "interests" }
    }
  }
}

结果

{
   ...
   "hits": { ... },
   "aggregations": {
      "all_interests": {
         "buckets": [
            {
               "key":       "music",
               "doc_count": 2
            },
            {
               "key":       "forestry",
               "doc_count": 1
            },
            {
               "key":       "sports",
               "doc_count": 1
            }
         ]
      }
   }
}

以上是对所有的雇员进行统计,我们也可以其中的一部分雇员进行组合查询统计,比如我们想知道叫smith的雇员最受欢迎的兴趣爱好。

GET /megacorp/employee/_search
{
  "query": {
    "match": {
      "last_name": "smith"
    }
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}

聚合还支持分级汇总,查询特定兴趣爱好的 员工的平均年龄

GET /megacorp/employee/_search
{
    "aggs" : {
        "all_interests" : {
            "terms" : { "field" : "interests" },
            "aggs" : {
                "avg_age" : {
                    "avg" : { "field" : "age" }
                }
            }
        }
    }
}

结果

  ...
  "all_interests": {
     "buckets": [
        {
           "key": "music",
           "doc_count": 2,
           "avg_age": {
              "value": 28.5
           }
        },
        {
           "key": "forestry",
           "doc_count": 1,
           "avg_age": {
              "value": 35
           }
        },
        {
           "key": "sports",
           "doc_count": 1,
           "avg_age": {
              "value": 25
           }
        }
     ]
  }

以上是关于elasticsearch权威指南笔记2 - 简单使用的主要内容,如果未能解决你的问题,请参考以下文章

elasticsearch-权威指南笔记-基础部分

elasticsearch权威指南笔记3 - 文档

小烨收藏ElasticSearch权威指南-搜索

Http权威指南---读书笔记

小烨收藏ElasticSearch权威指南-索引管理

js权威指南---学习笔记01