技术标签: Elasticsearch
通过使用 index API ,文档可以被 索引 —— 存储和使文档可被搜索。 但是首先,我们要确定文档的位置。正如我们刚刚讨论的,一个文档的 _index
、 _type 和 _id
唯一标识一个文档。
注:
ES7.x版本Type
已经移除, _type
字段那里变为固定值 _doc
!!!
我们可以提供自定义的 _id 值,或者让 index API 自动生成。
#语法:
PUT /{
index}/{
type}/{
id}
{
"field": "value",
...
}
把一些文档放到consumer索引中。我们将在consumer索引中索引一个简单的客户文档,其ID为1,如下所示:
PUT /customer/_doc/1?pretty
{
"name": "John Doe"
}
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
如上,我们可以看到在customer索引中成功地创建了一个新的customer文档。文档还有一个内部ID 1,我们在索引时指定了它。
如果你的数据没有自然的 ID, Elasticsearch 可以帮我们自动生成 ID 。 请求的结构调整为: 不再使用 PUT , 而是使用 POST :
POST /customer/_doc/?pretty
{
"name": "make Doe"
}
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "YWSApXEBsOGGEpTGJEmD",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 3,
"_primary_term" : 1
}
当我们索引一个文档,怎么确认我们正在创建一个完全新的文档,而不是覆盖现有的呢?
请记住, _index 、 _type 和 _id
的组合可以唯一标识一个文档。所以,确保创建一个新文档的最简单办法是,使用索引请求的 POST 形式让 Elasticsearch 自动生成唯一 _id:
POST /website/blog/
{
... }
然而,如果已经有自己的 _id ,那么我们必须告诉 Elasticsearch ,只有在相同的 _index 、 _type 和 _id 不存在时才接受我们的索引请求。这里有两种方式,他们做的实际是相同的事情。使用哪种,取决于哪种使用起来更方便。
第一种方法使用 op_type
查询-字符串参数:
PUT /website/blog/123?op_type=create
{
... }
第二种方法是在 URL 末端使用 /_create
:
PUT /website/blog/123/_create
{
... }
另一方面,如果具有相同的 _index 、 _type 和 _id 的文档已经存在,
Elasticsearch 将会返回 409 Conflict 响应码,以及如下的错误信息:
{
"error": {
"root_cause": [
{
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [3])",
"index_uuid": "UmtZgqkeTBKFQun4Xs3R1A",
"shard": "0",
"index": "customer"
}
],
"type": "version_conflict_engine_exception",
"reason": "[1]: version conflict, document already exists (current version [3])",
"index_uuid": "UmtZgqkeTBKFQun4Xs3R1A",
"shard": "0",
"index": "customer"
},
"status": 409
}
GET /customer/_doc/1?pretty
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 1,
"_seq_no" : 0,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "John Doe"
}
}
除了一个字段之外,这里没有发现任何异常的地方,说明我们找到了一个具有请求的ID 1的文档和另一个字段_source,它返回了我们从上一步索引的完整JSON文档。
如果只想检查一个文档是否存在–根本不想关心内容—那么用 HEAD
方法来代替 GET
方法。 HEAD
请求没有返回体,只返回一个 HTTP
请求报头:
curl -i -XHEAD http://localhost:9200/website/blog/123
如果文档存在, Elasticsearch 将返回一个 200 ok 的状态码:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
若文档不存在, Elasticsearch 将返回一个 404 Not Found 的状态码:
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=UTF-8
Content-Length: 0
Elasticsearch 的速度已经很快了,但甚至能更快。 将多个请求合并成一个,避免单独处理每个请求花费的网络延时和开销。 如果你需要从 Elasticsearch 检索很多文档,那么使用 multi-get 或者 mget API 来将这些检索请求放在一个请求中,将比逐个文档请求更快地检索到全部文档。
GET /_mget
{
"docs" : [
{
"_index" : "customer",
"_type" : "_doc",
"_id" : 2
},
{
"_index" : "customer",
"_type" : "_doc",
"_id" : 1
}
]
}
响应:
#! Deprecation: [types removal] Specifying types in multi get requests is deprecated.
{
"docs" : [
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "2",
"_version" : 1,
"_seq_no" : 6,
"_primary_term" : 1,
"found" : true,
"_source" : {
"name" : "John Doe"
}
},
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"found" : false
}
]
}
注意:
提示 弃用:[types removal]不建议在多个get请求中指定types。
如果想检索的数据都在相同的 _index 中(甚至相同的 _type 中),则可以在 URL 中指定默认的 /_index 或者默认的 /_index/_type 。
你仍然可以通过单独请求覆盖这些值:
GET /website/blog/_mget
{
"docs" : [
{
"_id" : 2 },
{
"_type" : "pageviews", "_id" : 1 }
]
}
事实上,如果所有文档的 _index 和 _type 都是相同的,你可以只传一个 ids 数组,而不是整个 docs 数组:
GET /website/blog/_mget
{
"ids" : [ "2", "1" ]
}
实际上 Elasticsearch 并不在原有的基础上进行更新。每当我们进行更新时,Elasticsearch 执行步骤如下:
在 Elasticsearch 中 文档是 不可改变 的,不能修改它们。相反,如果想要更新现有的文档,需要 重建索引 或者进行替换, 我们可以使用相同的 index API 进行实现,在 索引文档 中已经进行了讨论。
PUT /website/_doc/123
{
"title": "My first blog entry",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}
在响应体中,我们能看到 Elasticsearch 已经增加了 _version 字段值:
{
"_index" : "website",
"_type" : "_doc",
"_id" : "123",
"_version" : 2,
"created": false
}
update 请求最简单的一种形式是接收文档的一部分作为 doc
的参数, 它只是与现有的文档进行合并。对象被合并到一起,覆盖现有的字段,增加新的字段。
#此示例显示如何通过将名称字段更改为“Jane xiang”来更新以前的文档(ID为1):
POST /customer/_update/1?pretty
{
"doc": {
"name": "Jane xiang" }
}
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 2,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 4,
"_primary_term" : 1
}
#此示例演示如何通过将名称字段更改为“Jane Doe”来更新以前的文档(ID为1),同时向其添加年龄字段:
POST /customer/_update/1?pretty
{
"doc": {
"name": "Jane Doe", "age": 20 }
}
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 5,
"_primary_term" : 1
}
脚本可以在 update API中用来改变 _source
的字段内容, 它在更新脚本中称为 ctx._source
。 例如,我们可以使用脚本来增加博客文章中 views 的数量:
POST /website/1/_update
{
"script" : "ctx._source.views+=1"
}
我们也可以通过使用脚本给 tags
数组添加一个新的标签。在这个例子中,我们指定新的标签作为参数,而不是硬编码到脚本内部。 这使得 Elasticsearch 可以重用这个脚本,而不是每次我们想添加标签时都要对新脚本重新编译:
POST /website/1/_update
{
"script" : "ctx._source.tags+=new_tag",
"params" : {
"new_tag" : "search"
}
}
获取文档并显示最后两次请求的效果:
{
"_index": "website",
"_type": "_doc",
"_id": "1",
"_version": 5,
"found": true,
"_source": {
"title": "My first blog entry",
"text": "Starting to get the hang of this...",
"tags": ["testing", "search"],
"views": 1
}
}
我们甚至可以选择通过设置 ctx.op
为 delete
来删除基于其内容的文档:
POST /website/1/_update
{
"script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
"params" : {
"count": 1
}
}
删除文档的语法和我们所知道的规则相同,只是使用 DELETE
方法:
DELETE /customer/_doc/1
响应:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 4,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 1
}
如果文档没有找到,我们将得到 404 Not Found 的响应码和类似这样的响应体:
{
"_index" : "customer",
"_type" : "_doc",
"_id" : "1",
"_version" : 5,
"result" : "not_found",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 1
}
即使文档不存在( Found 是 false ), _version 值仍然会增加。这是 Elasticsearch 内部记录本的一部分,用来确保这些改变在跨多节点时以正确的顺序执行。
文章浏览阅读74次。思路:num%r得到末位r进制数,num/r得到num去掉末位r进制数后的数字。得到的末位r进制数采用头插法插入链表中,更新num的值,循环计算,直到num为0,最后输出链表。//重置,s指针与头指针指向同一处。//更新num的值,至num为0退出循环。//末位r进制数存入s数据域中。//头插法插入链表中(无头结点)//定义头指针为空,s指针。= NULL) //s不为空,输出链表,栈先入后出。
文章浏览阅读176次。武汉芯源半导体积极参与推动中国的大学教育改革以及注重电子行业的人才培养,建立以企业为主体、市场为导向、产学研深度融合的技术创新体系。2023年3月,武汉芯源半导体开发者扶持计划正式开始进行,以打造更为丰富的CW32生态社区。_cw32开发者扶持计划申请
文章浏览阅读5.7k次。2014年底买的一块2TB希捷机械硬盘ST2000DM001-1ER164,用了两年更换了主板、CPU等,后来出现开机不识别的情况,具体表现为:关机后开机,找不到硬盘,就进入BIOS了,只要在BIOS状态下待机半分钟左右再重启,硬盘就会出现。进入系统后,重启(这个过程中主板对硬盘始终处于供电状态),也不会出现不识别硬盘的现象。就好像是硬盘或主板上某个电容坏了一样,刚开始给硬盘通电的N秒钟内电容未能..._st2000dm001不认盘
文章浏览阅读1.5k次。ADO.NET的数据源不单单是DB,也可以是XML、ExcelADO.NET连接数据源有两种交互模式:连接模式和断开模式两个对应的组件:数据提供程序(数据提供者)&DataSetSqlConnectionStringBuilder——连接字符串Connection对象用于开启程序和数据库之间的连接public SqlConnection c..._列举ado.net在操作数据库时,常用的对象及作用
文章浏览阅读113次。【代码】Android 自定义对话框不能铺满全屏。_android dialog宽度不铺满
文章浏览阅读331次。Redis的主从集群与哨兵模式Redis的主从模式全量同步增量同步Redis主从同步策略流程redis主从部署环境哨兵模式原理哨兵模式概述哨兵模式的作用哨兵模式项目部署Redis的主从模式1、Redis虽然读取写入的速度都特别快,但是也会产生读压力特别大的情况。2、为了分担读压力,Redis支持主从复制,保证主数据库的数据内容和从数据库的内容完全一致。3、Redis的主从结构可以采用一主多从或者级联结构,Redis主从复制可以根据是否是全量分为全量同步和增量同步。全量同步Redis全量复制一般发_redis的主从和哨兵集群
文章浏览阅读116次。作者:brightwang原文:https://www.jianshu.com/p/ab9aa8d4df7d最近我遇到了一个bug,我试着通过Rails在以“utf8”编码的MariaDB中保存一个UTF-8字符串,然后出现了一个离奇的错误:Incorrect string value: ‘ð 我用的是UTF-8编码的客户端,服务器也是UTF-8编码的,数据库也是,就连要保存的这个字符串“????..._mysql utf8的作用
文章浏览阅读278次。毕业这么久了,最近闲来准备把毕设过程中的代码整理公开一下,所有代码其实都是网上找的,但都是经过调试能跑通的,希望对需要的人有用。PS:里边很多注释不讲什么意思了,能看懂的自然能看懂。_matlab图像比较
文章浏览阅读73次。思路: screen分为普通和复杂两种,普通的功能大部分是页面跳转以及简单的crud数据,复杂的单独弄出来 跳转普通的screen,直接根据配置文件调整设置<layouts> <loyout screenId="0" bg="bg_start" name="start" defaultWinId="" bgm="" remark=""> ..._libgdx ui 布局
文章浏览阅读3k次,点赞2次,收藏13次。playwright-python 处理Text input和Checkboxs 和 radio buttonsText input输入框输入元素,直接用fill方法即可,支持 ,,[contenteditable] 和<label>这些标签,如下代码:page.fill('#name', 'Peter');# 日期输入page.fill('#date', '2020-02-02')# 时间输入page.fill('#time', '13-15')# 本地日期时间输入p_playwright checkbox
文章浏览阅读596次,点赞5次,收藏6次。这是我看到最最详细的安装说明文章了,必须要给赞!学习了,也配置了,成功的一批!真不知道还有什么可补充的了,在此做个推广,喜欢的小伙伴,走起!_win10 php 安装swoole
文章浏览阅读1k次。今天想实现页面的自适应,本来用的是栅格,但效果不理想,就想起了rem布局。以前使用rem布局,都是在原生html里,还没在框架里使用过,百度没百度出来,就自己琢磨,不知道方法规范不规范,反正成功了,操作如下:1、下载flexible.js2、引入到angular项目里3、根据自己的需要修改细节3.1、在flexible.js里修改每份的像素,3.2、引入cssrem插件,在设置里设..._angular 使用rem