ElasticSearch之一——索引
ElasticSearch索引
ElasticSearch 是一个分布式可扩展的实时搜索引擎,它建立在开源搜索引擎框架Apache Lucene基础上。
ElasticSearch 不但包括了全文搜索功能,还支持一下特性:
1、分布式实时文件存储,将每一个字段都编入索引,使其可以被搜索;
2、实时分析的分布式搜索引擎;
3、可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据;
1、与ElasticSearch 通信
Java API
如果使用Java,ElasticSearch(简写ES) 内置了两个客户端:
1、节点客户端:以一个无数据节点的身份加入一个集群,它自身没有数据,但它知道什么数据在集群的哪一个节点上,然后就可以将请求转发到正确的节点上。
2、传输客户端:它本身并不加入集群,而用来向远程集群发送请求。
这两个客户端都使用ElasticSearch的传输协议,通过9300端口与java客户端进行通信,集群中的每个节点也是通过9300端口进行通信。
HTTP RESTful API
其它非Java语言可以采用HTTP协议,通过9200端口与ES的RESTful API进行通信。
向ES发出HTTP请求,例如请求集群中文件的数量:
http://localhost:9200/_count?pretty
ES返回一个json字符串:
{
count: 0,
_shards: {
total: 0,
successful: 0,
failed: 0
}
}
2、文档
ES是面向文档型数据库,并为它们建立索引,这样我们可以在ES中索引、搜索、排序和过滤这些文档。
ES使用JSON作为文档序列化的格式,例如:
一个文档不只包含了数据。它还包含了元数据(metadata) —— 关于文档的信息。有三个元数据元素是必须存在的,它们是:
名字 | 说明 |
---|---|
_index |
文档存储的地方 |
_type |
文档代表的对象种类 |
_id |
文档的唯一编号 |
一篇文档通过 _index, _type以及_id来确定它的唯一性,下面对比了这几个名词与关系型数据库的关系:
关系型数据库 | 数据库 | 表 | 行 | 列 |
ElasticSearch | 索引 | 类型 | 文档 | 字段 |
一个ES集群可以包含多个索引(数据库),每个索引又包含了很多类型(表),类型中包含了很多文档(行),每个文档又包含了很多字段(列)。
在ES中,索引有多重含义:
1、索引(名词),一个索引就类似与传统关系型数据库中的数据库,这里就是存储相关文档的地方;
2、索引(动词),把一个文档存储到一个索引中的过程,这样它才能被检索,这个过程类似于SQL中的INSERT命令;
3、反向索引,通常每个文档中的字段都被创建了反向索引,如果一个字段没有反向索引,那么它将不能被搜索。
下面演示通过HTTP请求如何建立索引:
1、添加文档(PUT请求)
curl "127.0.0.1:9200/sina/employee/11412" -d '{"name":"chenqi","age":30}'
返回值:
{"_index":"sina","_type":"employee","_id":"","_version":,"created":true}
sina是索引名,employee是类型名,11412是文档ID,它们组合构成了请求url的路径;
注意:_version 字段表示文档的版本,每当文档发生变化时,_version就会增大。
总结下添加文档的方法:
PUT /{index}/{type}/{id}
{
"field": "value",
...
}
如果在请求中不指定id,ES会自动分配一个自增ID;
如果指定的文档id在索引中已存在,则更新原文档,此时文档的_version会增加1,并且_created字段为false;
如果只打算在文档不存在的情况下才创建新文档,则使用下面两种方法之一即可:
PUT /{index}/{type}/{id}?op_type=create
PUT /{index}/{type}/{id}/_create
创建成功返回201 Created;如果文档ID已存在,则请求失败,并返回409 Conflict。
2、局部更新
使用更新请求最简单的一种用途就是添加新数据。新的数据会被合并到现有数据中,而如果存在相同的字段,就会被新的数据所替换。
例如我们可以为我们的博客添加tags和views字段:
POST /website/blog//_update
{
"doc" : {
"tags" : [ "testing" ],
"views":
}
}
ES还可以使用脚本来更新文档,例如:
POST /sina/employee//_update
{
"script" : "ctx._source.age+=1"
}
更新一篇可能不存在的文档,使用upsert
参数来设定文档不存在时,它应该被创建:
POST /website/pageviews//_update
{
"script" : "ctx._source.views+=1",
"upsert": {
"views":
}
}
3、检索文档(GET请求)
例如:
curl "127.0.0.1:9200/sina/employee/11412"
返回值:
{"_index":"sina","_type":"employee","_id":"","_version":,"found":true,"_source":{"name":"chenqi","age":}}
如果请求一个不存在的文档,如:
curl "127.0.0.1:9200/sina/employee/11410"
则返回:
{"_index":"sina","_type":"employee","_id":"","found":false}
也可以检索所有文档(不指定文档ID或类型ID),例如:
URL | 说明 |
---|---|
/_search |
搜索所有的索引和类型 |
/gb/_search |
搜索索引gb 中的所有类型 |
/gb,us/_search |
搜索索引gb 以及us 中的所有类型 |
/g*,u*/_search |
搜索所有以g 或u 开头的索引中的所有类型 |
/gb/user/_search |
搜索索引gb 中类型user 内的所有文档 |
/gb,us/user,tweet/_search |
搜索索引user 以及tweet 中类型gb and us 内的所有文档 |
/_all/user,tweet/_search |
搜索所有索引中类型为user 以及tweet 内的所有文档 |
注意:当我们在索引一个文档的时候,ES会将所有字段的值都汇总到一个大的字符串中,并将它索引成一个特殊的字段_all:
{
"tweet": "However did I manage before Elasticsearch?",
"date": "2014-09-14",
"name": "Mary Jones",
"user_id": 1
}
就好像我们已经添加了一个叫做_all
的字段:
"However did I manage before Elasticsearch? 2014-09-14 Mary Jones 1"
利用all字段,可以检索包含指定字符串的文档,如下面,搜索包含mary的文档:
GET /_search?q=mary
还可以根据指定字段来检索文档:
http://10.69.2.49:9200/_search?q=age:28
只返回字段age=28的文档;
字段前加前缀"+"
表示必须要满足我们的查询匹配条件,而前缀"-"
则表示绝对不能匹配条件。没有+
或者-
的表示可选条件。匹配的越多,文档的相关性就越大。
再实现一个复杂查询:
- 字段
name
包含"mary"
或"john"
date
大于2014-09-10
_all
字段中包含"aggregations"
或"geo"
q=+name:(mary john) +date:>-- +(aggregations geo)
另外,size和from参数可以控制翻页:
参数 | 说明 |
---|---|
size |
每次返回多少个结果,默认值为10 |
from |
忽略最初的几条结果,默认值为0 |
假设每页显示5条结果,那么1至3页的请求就是:
GET /_search?size=
GET /_search?size=&from=
GET /_search?size=&from=
最后,使用source参数可以指定只返回文档的某几个字段,例如:
http://10.69.2.49:9200/_search?q=age:28&_source=name
http://10.69.2.49:9200/sina/employee/11412/_source
4、检查文档(HEAD请求)
curl -i -XHEAD /{index}/{type}/{id}
存在返回200,否则返回404。
5、删除文档(DELETE请求):
curl "127.0.0.1:9200/sina/employee/11412" -XDELETE
删除文档也会增加_version字段。
3、搜索
前面提到了可以在GET请求中以q=field:value 的形式进行简易查询,此外,ES还提供了更加强大的Query DSL(Domain Specific Language)查询语言,通过它可以完成更加复杂的搜索任务。
例如下面两种查询方式等价:
curl "127.0.0.1:9200/sina/_search" -d '{"query":{"match":{"age":28}}}' curl "127.0.0.1:9200/sina/_search?q=age:28"
其中,json串{"query":{"match":{"age":28}}} 就是一个Query DSL。
下面是一个更为复杂的Query DSL,用于找到name字段等于"chenqi"的文档,并且附加了一个过滤条件:age>30。
{
"query":{
"filtered":{
"filter":{
"range":{
"age":{"gt":}
}
}, "query":{
"match":{
"name":"chenqi"
}
}
}
}
}
注:将match换成match_phrase,可以进行段落或短语的精确匹配。
4、冲突处理
Elasticsearch是分布式的。当文档被创建、更新或者删除时,新版本的文档就会被复制到集群中的其他节点上。ES即是同步的又是异步的,也就是说复制的请求被平行发送出去,然后可能会混乱地到达目的地。这就需要一种方法能够保证新的数据不会被旧数据所覆盖。
我们在上文提到每当有索引、put和删除的操作时,无论文档有没有变化,它的_version都会增加。Elasticsearch使用_version来确保所有的改变操作都被正确排序。如果一个旧的版本出现在新版本之后,它就会被忽略掉。
我们可以利用_version的优点来确保我们程序修改的数据冲突不会造成数据丢失。我们可以按照我们的想法来指定_version的数字。如果数字错误,请求就是失败。
我们来创建一个新的博文:
PUT /website/blog//_create
{
"title": "My first blog entry",
"text": "Just trying this out..."
}
此时,文档的version=1;
现在,我们试着重新索引文档以保存变化,我们这样指定了version
的数字:
PUT /website/blog/?version=
{
"title": "My first blog entry",
"text": "Starting to get the hang of this..."
}
当索引中文档的_version
是1
时,更新才生效,更新后version=2。
当我们再执行同样的索引请求,并依旧指定version=1
时,ES就会返回一个409 Conflict
的响应码,返回内容如下:
{
"error" : "VersionConflictEngineException[[website][2] [blog][1]:
version conflict, current [], provided []]",
"status" :
}
这里面指出了文档当前的_version
数字是2
,而我们要求的数字是1
。
所有的有关于更新或者删除文档的API都支持version
这个参数,有了它你就通过修改你的程序来使用并发控制。
参考文档:
http://www.learnes.net/data/mget.html
ElasticSearch之一——索引的更多相关文章
- ElasticSearch+Kibana 索引操作
ElasticSearch+Kibana 索引操作 一 前言 ElasticiSearch 简介 ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索引 ...
- ES 10 - Elasticsearch的索引别名和索引模板
目录 1 索引模板概述 1.1 什么是索引模板 1.2 索引模板中的内容 1.3 索引模板的用途 2 创建索引模板 3 查看索引模板 4 删除索引模板 5 模板的使用建议 5.1 一个index中不能 ...
- elasticsearch的索引操作和文档操作总结
参考文档:https://es.xiaoleilu.com/010_Intro/00_README.html 一.索引操作 1.查看当前节点的所有的index 查看当前节点的所有的index [roo ...
- elasticsearch的索引自动清理及自定义清理
近发现elasticsearch近期索引文件大的吓人,清理了下之前的索引文件,发现服务器性能大大的减轻了一半,想一直保留近一个月的索引文件,但是又不想每个月手动清楚,在此写了一个小脚本 查询索引: c ...
- ELK学习笔记之ElasticSearch的索引详解
0x00 ElasticSearch的索引和MySQL的索引方式对比 Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤.特别是它对多条件的过滤支持非常好,比如年龄 ...
- elasticsearch删除索引报错【原】
如果elasticsearch删除索引报错 curl -X DELETE 'http://10.73.26.66:9200/httpd-34-2017.08.15' {"error" ...
- Spring Boot + Elasticsearch 实现索引的日常维护
全文检索的应用越来越广泛,几乎成了互联网应用的标配,商品搜索.日志分析.历史数据归档等等,各种场景都会涉及到大批量的数据,在全文检索方面,方案无外乎Lucene.Solr.Elasticsearch三 ...
- Spring Boot + Elasticsearch 实现索引批量写入
在使用Eleasticsearch进行索引维护的过程中,如果你的应用场景需要频繁的大批量的索引写入,再使用上篇中提到的维护方法的话显然效率是低下的,此时推荐使用bulkIndex来提升效率.批写入数据 ...
- 数组如何在ElasticSearch中索引
一.简介 在ElasticSearch里没有专门的数组类型,任何一个字段都可以有零个和多个值.当字段值的个数大于1时,字段类型就变成了数组. 下面以视频数据为例,介绍ElasticSearch如何索引 ...
- 【ElasticSearch】索引重建
ElasticSearch索引重建 ElasticSearch索引一旦建立,便不可修改索引字段类型(允许增加或者删除该字段) 例如从Integer类型修改为long类型,这是不被允许的,错误信息如下: ...
随机推荐
- Maven 库
mvnrepository https://mvnrepository.com/ 最方便查询的库 <repositories> <repository> <id&g ...
- HTMLTestRunner修改Python3的版本
在拜读虫师大神的Selenium2+Python2.7时,发现生成HTMLTestRunner的测试报告使用的HTMLTestRunner的模块是用的Python2的语法.而我本人比较习惯与Pytho ...
- 动画: ThemeAnimation(主题动画)
背水一战 Windows 10 之 动画 PopInThemeAnimation - 控件出现时的动画 PopOutThemeAnimation - 控件消失时的动画 FadeInThemeAnima ...
- 如何让ie 7 支持box-shadow
box-shadow是一个很好用并且也常用的css 3属性,但是,如果我们要保证它能在ie 8及更低的版本下运行的话,需要借助一些其他的插件或文件.在这里我主要讲一下,如何用PIE.htc来解决ie ...
- WebApi支持命名空间重名问题
using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.Linq; ...
- target file里面的每个string字段的双引号怎么去掉
今天在做一个extract,把数据库里面的表经过一些过程,最终输入到flat file中. 但是最终的结果中,每个target file的string字段,含有双引号如下: NAME_ID NA ...
- [学习笔记]tarjan求割边
上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...
- java integer对象判断两个数字是否相等
java integer对象判断两个数字是否相等,不一定对 问题发生的背景:javaweb的项目,起先,因为在java中实体类中的int类型在对象初始化之后会给int类型的数据默认赋值为0,这样在很多 ...
- 【poj3241】 Object Clustering
http://poj.org/problem?id=3241 (题目链接) MD被坑了,看到博客里面说莫队要写曼哈顿最小生成树,我就写了一个下午..结果根本没什么关系.不过还是把博客写了吧. 转自:h ...
- DayuCMS 1.525 /include/global.func.php Foreground Arbitrary Code Execution
catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 Relevant Link: http://joychou.org/in ...