ES

Elasticsearch 是一个实时的分布式搜索分析引擎,它能让你以一个之前从未有过的速度和规模,去探索你的数据。 它被用作全文检索、结构化搜索、分析以及这三个功能的组合


大部分数据库在从你的数据中提取可用知识时出乎意料的低效。 当然,你可以通过时间戳或精确值进行过滤,但是它们能够进行全文检索、处理同义词、通过相关性给文档评分么? 它们从同样的数据中生成分析与聚合数据吗?最重要的是,它们能实时地做到上面的那些而不经过大型批处理的任务么?


Elasticsearch是 面向文档 的,意味着它存储整个对象或 文档_。在 Elasticsearch 中,你 对文档进行索引、检索、排序和过滤--而不是对行列数据。这是一种完全不同的思考数据的方式,也是 Elasticsearch 能支持复杂全文检索的原因。


例:存储雇员数据
这将会以 雇员文档 的形式存储:一个文档代表一个雇员。存储数据到 Elasticsearch 的行为叫做 索引 ,但在索引一个文档之前,需要确定将文档存储在哪里。
一个 Elasticsearch 集群可以 包含多个 索引 ,相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性 。


索引文档:
对于雇员目录,我们将做如下操作:
每个雇员索引一个文档,包含该雇员的所有信息。
每个文档都将是 employee 类型 。
该类型位于 索引 megacorp 内。
该索引保存在我们的 Elasticsearch 集群中。
具体代码操作如下:


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


检索文档:
简单地执行 一个 HTTP GET 请求并指定文档的地址——索引库、类型和ID。 使用这三个信息可以返回原始的 JSON 文档:
具体代码:GET /megacorp/employee/1
返回结果:
{
  "_index" :   "megacorp",  //索引
  "_type" :    "employee",  //类型
  "_id" :      "1", //ID
  "_version" : 1,
  "found" :    true,
  "_source" :  {
      "first_name" :  "John",
      "last_name" :   "Smith",
      "age" :         25,
      "about" :       "I love to go rock climbing",
      "interests":  [ "sports", "music" ]
}
}
将 HTTP 命令由 PUT 改为 GET 可以用来检索文档,同样的,可以使用 DELETE 命令来删除文档,以及使用 HEAD 指令来检查文档是否存在。如果想更新已存在的文档,只需再次 PUT


搜索所有雇员:GET /megacorp/employee/_search
搜索姓氏为 ``Smith`` 的雇员:GET /megacorp/employee/_search?q=last_name:Smith


Elasticsearch 提供一个丰富灵活的查询语言叫做 查询表达式 , 它支持构建更加复杂和健壮的查询。领域特定语言 (DSL), 指定了使用一个 JSON 请求。
GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "last_name" : "Smith"
        }
    }
}


GET /megacorp/employee/_search
{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "last_name" : "smith" 
                }
            },
            "filter": {
                "range" : {
                    "age" : { "gt" : 30 } 
                }
            }
        }
    }
}


全文搜索:
GET /megacorp/employee/_search
{
    "query" : {
        "match" : {
            "about" : "rock climbing"
        }
    }
}
返回结果:curl -X GET "localhost:9200/website/blog/123?pretty"
{
   ...
   "hits": {
      "total":      2, //匹配结果数量
      "max_score":  0.16273327,    
      "hits": [
         {
            ...
            "_score":         0.16273327, //匹配结果得分
            "_source": {
               "first_name":  "John",
               "last_name":   "Smith",
               "age":         25,
               "about":       "I love to go rock climbing",
               "interests": [ "sports", "music" ]
            }
         },
         {
            ...
            "_score":         0.016878016, //匹配结果得分
            "_source": {
               "first_name":  "Jane",
               "last_name":   "Smith",
               "age":         32,
               "about":       "I like to collect rock albums",
               "interests": [ "music" ]
            }
         }
      ]
   }
}


短语搜索:
GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {   //短语搜索,全文搜索为match
            "about" : "rock climbing"
        }
    }
}
返回结果:
{
   ...
   "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" ]
            }
         }
      ]
   }
}
高亮搜素:
GET /megacorp/employee/_search
{
    "query" : {
        "match_phrase" : {
            "about" : "rock climbing"
        }
    },
    "highlight": {
        "fields" : {
            "about" : {}
        }
    }
}
Elasticsearch 有一个功能叫聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。
分析:挖掘出雇员中最受欢迎的兴趣爱好
具体代码:
GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": { "field": "interests" }
    }
  }
}
可以直接添加适当的查询来组合查询:
GET /megacorp/employee/_search
{
  "query": {
    "match": {
      "last_name": "smith"
    }
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}




具体原理跳过.......


文档元数据: 一个文档不仅仅包含它的数据 ,也包含 元数据 —— 有关 文档的信息。 三个必须的元数据元素如下:
_index: 文档在哪存放
_type: 文档表示的对象类别
_id: 文档唯一标识
一个文档的 _index 、 _type 和 _id 唯一标识一个文档。 
我们可以提供自定义的 _id 值:
PUT /{index}/{type}/{id}
{
  "field": "value",
  ...
}
或者让 index API 自动生成:
POST /website/blog/
{
  "title": "My second blog entry",
  "text":  "Still trying this out...",
  "date":  "2014/01/01"
}


Elasticsearch 响应体如下所示:
{
   "_index":    "website",
   "_type":     "blog",
   "_id":       "123",
   "_version":  1, //在 Elasticsearch 中每个文档都有一个版本号。当每次对文档进行修改时(包括删除), _version 的值会递增
   "created":   true
}


取回一个文档;
1. GET /website/blog/123?pretty //在请求的查询串参数中加上 pretty 参数,使得 JSON 响应体更加可读
2. GET /website/blog/123?_source=title,text //取回一个文档的title和text字段
3. GET /website/blog/123/_source //只得到_socure字段
检查文档是否存在:
1. HEAD /website/blog/123 //如果文档存在, Elasticsearch 将返回一个 200 ok 的状态码
//若文档不存在, Elasticsearch 将返回一个 404 Not Found 的状态码
更新整个文档:
1. PUT /website/blog/123 //ES中的文档是不可改变的,如果要修改他,只能用相同的索引去替换他,但是旧的文档不会立即消失,会在后台保留一段时间
{
  "title": "My first blog entry",
  "text":  "I am starting to get the hang of this...",
  "date":  "2014/01/02"
}


创建新文档:
1. _index 、 _type 和 _id 的组合可以唯一标识一个文档,所以,确保创建一个新文档的最简单办法是,使用索引请求的 POST 形式让 Elasticsearch 自动生成唯一 _id 
POST /website/blog/
{ ... }
2. 如果已经有自己的 _id ,那么我们必须告诉 Elasticsearch ,只有在相同的 _index 、 _type 和 _id 不存在时才接受我们的索引请求
PUT /website/blog/123?op_type=create
{ ... }
或者:
PUT /website/blog/123/_create
{ ... }
如果创建新文档的请求成功执行,Elasticsearch 会返回元数据和一个 201 Created 的 HTTP 响应码。
另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,Elasticsearch 将会返回 409 Conflict 响应码,以及一些错误信息
删除文档:
1. DELETE /website/blog/123
处理冲突:
1. 悲观并发控制,阻塞访问资源以防止冲突
2. 乐观并发控制,不做阻塞处理,而是重新更新,使用新的数据或者将相关情况反馈给用户
文档的部分更新:
1. 请求最简单的一种形式是接收文档的一部分作为 doc 的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段
POST /website/blog/1/_update
{
   "doc" : {
      "tags" : [ "testing" ],
      "views": 0
   }
}
取回多个文档:
将多个请求合并成一个,避免单独处理每个请求花费的网络延时和开销。
代价较小的批量操作:
bulk API 允许在单个步骤中进行多次 create 、 index 、 update 或 delete 请求。
如:POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }} 
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title":    "My first blog post" }
{ "index":  { "_index": "website", "_type": "blog" }}
{ "title":    "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict" : 3} }
{ "doc" : {"title" : "My updated blog post"} } 




查询全文数据要微妙的多。我们问的不只是“这个文档匹配查询吗”,而是“该文档匹配查询的程度有多大?”换句话说,该文档与给定查询的相关性如何?
我们很少对全文类型的域做精确匹配。相反,我们希望在文本类型的域中搜索。不仅如此,我们还希望搜索能够理解我们的 意图 :


Elasticsearch 使用一种称为 倒排索引 的结构,它适用于快速的全文搜索。一个倒排索引由文档中所有不重复词的列表构成,对于其中每个词,有一个包含它的文档列表。
Quick 可以小写化为 quick 。
foxes 可以 词干提取 --变为词根的格式-- 为 fox 。类似的, dogs 可以为提取为 dog 。
jumped 和 leap 是同义词,可以索引为相同的单词 jump 
分词和标准化的过程称为 分析






查询
基本的查询某一条语句
1. itslaw2/itslaw2/1502
返回结果更具有可读性
2. itslaw2/itslaw2/1502?pretty
只返回caseType,paragraphs字段
3. itslaw2/itslaw2/1502?_source=caseType,paragraphs
不需要任何元数据的查询
4.itslaw2/itslaw2/1502/_source
基于第四条只返回部分字段
5.itslaw2/itslaw2/1502/_source?_source=caseType,paragraphs


增加
1. itslaw2/itslaw2/0000000
{
  "title": "My first blog entry",
  "text":  "I am starting to get the hang of this...",
  "date":  "2014/01/02"
}
创建新文档:
1. _index 、 _type 和 _id 的组合可以唯一标识一个文档,所以,确保创建一个新文档的最简单办法是,使用索引请求的 POST 形式让 Elasticsearch 自动生成唯一 _id 
POST /website/blog/
{ ... }
2. 如果已经有自己的 _id ,那么我们必须告诉 Elasticsearch ,只有在相同的 _index 、 _type 和 _id 不存在时才接受我们的索引请求
PUT itslaw2/itslaw2/0000000?op_type=create
{ ... }
或者:
PUT itslaw2/itslaw2/0000000/_create
{ ... }
如果创建新文档的请求成功执行,Elasticsearch 会返回元数据和一个 201 Created 的 HTTP 响应码。
另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,Elasticsearch 将会返回 409 Conflict 响应码,以及一些错误信息


删除
1. DELETE /website/blog/123
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值