2.7 对文档的其他操作
Elasticsearch提供多种途径对文档进行诸如获取信息、增、删、改、更新等相关操作。
2.7.1 获取指定的文档信息
可以通过GET方法来获取指定文档的详细信息,代码段2.21演示了查看索引weibo下类型文件名为wb且id号为2的记录信息的方法,注意这里的HTTP操作方式是GET。
//代码段2.21:获取指定文档信息 curl-XGET'http://localhost:9200/weibo/wb/2'
示例返回结果如下所示,其中在_source段中的内容就是文档中的详细内容。
{ "_index": "weibo", //索引名 "_type": "wb", //类型名 "_id": "2", //ID号 "_version":1, //版本号 "found": true, "_source": { "user": "LiMing", //详细信息 "post_date": "2016-10-30T14:00:00", "message”: "Hello Tom" } }
除了上面的方法外,还可设置想要显示或屏蔽的结果。代码段2.22演示了关闭_source过滤器后的效果(注:语句中的问号表示其后是参数,其中pretty表示返回的结果中显示缩进以方便阅读)。执行上述语句后,在输出的结果中将不再带有详细内容。
//代码段2.22: source过滤器 curl-XGET'http://localhost:9200/weibo/wb/2? pretty&_source=false'
代码段2.23中,演示了如何只显示特定字段的方法(此例只显示_source为user的内容):
//代码段2.23:显示特定 field的方法 curl-XGET'http://localhost:9200/weibo/wb/2? _source=user'
针对上述语句的返回结果将只带有user这个字段,如下所示:
{ "_index": "weibo", "_type": "wb", "_id": "2", "_version":1, "found": true, "_source": { "user": "LiMing" } }
2.7.2 删除文档中的信息
可以使用DELETE方法来删除文档中的相应信息。执行代码段2.24,会删除weibo索引中类型文件为wb且id号为2的信息。
//代码段2.24:删除指定的文档信息 curl-XDELETE'http://localhost:9200/weibo/wb/2'
针对上述语句的示例返回值如下,表明删除成功。
{ "found": true, "_index": "weibo", "_type": "wb", "_id": "2", "_version":2, "result": "deleted", "_shards": { "total":2, "successful":2, "failed":0 } }
2.7.3 数据更新
如果需要对索引文档中的类型或其中的文档进行更新,需要用Elasticsearch提供的UpdateAPI来实现。它的处理过程是先取出文档,运行指定脚本,之后更新文档。代码段2.25是在索引weibo中的类型文件wb中增加id为3的文档信息(给定了4个field,即user、post_date、message、like,这里的“like”的含义是表示针对此条微博点赞的数量)。
//代码段2.25:直接向索引文件中指定的 id中录入信息 curl-XPUT http://localhost:9200/weibo/wb/3-d'{ //直接指定id号,这里的HTTP方法是PUT "user": "LiMing", "post_date": "2016-10-31T14:00:00", "message": "Hello Tim", "like":3 }'
下面使用script定制函数形式的命令对数据进行更新。需要注意的是,Elasticsearch默认不允许使用script,因此需要在{es_home}/config/elasticsearch.yml配置文件末尾加入以下三行配置信息并重启Elasticsearch:
script.engine.groovy.inline.update: true script.inline: true script.stored: true
可以通过使用UpdateAPI将上述这个文档中的“like”数值增加,实现方法如代码段2.26所示,注意这里的“ctx._source”表示本文档的内容,ctx._source.like表示文档中某个具体的字段(这里是指like字段),而params是拟使用的新参数值。
//代码段2.26:通过 Update API更新数据 curl-XPOST http://localhost:9200/weibo/wb/3/_update-d'{ "script":{ "inline":"ctx._source.like+=params.count", "lang":"painless", "params":{ "count":4 } } }
针对上面的例子,执行完上述语句后的索引数据如图2.10所示,注意字段中的“like”值已经由原来的3变为7。
图2.10 更新like字段后的索引数据
Tips:上面的代码中,“ctx._source”表示document内容,ctx._source.like表示该document中具体的fields是“like”字段;params表示为变量赋值为4。图2.10中的结果可以通过curl-XGET http://localhost:9200/weibo/wb/3命令得到。
上述的UpdateAPI是针对于数值型数据的增、删、改操作。类似地,也可以完成对字符型数据的更新。代码段2.27录入了id号为5、针对索引文件为weibo、类型文件名为wb的部分微博数据字段(含user、post_data、message、tags等)。
//代码段2.27:直接向指定的 id中录入信息 curl-XPOST http://localhost:9200/weibo/wb/5-d'{//注意这里使用的HTTP方法是POST "user": "LiMing", "post_date": "2016-11-02T14:00:00", "message": "Hello Lily", "script.engine.groovy.inline.update": "true", "script.inline": "true", "script.stored": "true", "tags": [ "Hello" ] }'
代码段2.28的作用是修改了上述语句执行结果中的tag信息并增加了新的内容(即:在tag中增加了新的内容)。修改后的文档信息如图2.11所示(可通过curl-XGET http://localhost:9200/weibo/wb/5命令得到运行结果)。
//代码段2.28:通过 Update API更新信息 curl-XPOSThttp://localhost:9200/weibo/wb/5/_update-d'{ //注意这里的POST方法 "script": { "inline": "ctx._source.tags.add(params.tag)", "lang": "painless", "params": { "tag": "Today is a nice day! " } } }'
由于Elasticsearch处理的文档多是非结构化的信息,因此它可以不像关系型数据库一样,文档中各记录的字段有可能不一样。利用UpdateAPI,不仅可以像上述那样更新数据,也可以修改文档结构(如只在某一id的记录上增加新的字段)。代码段2.29完成在指定的文档中增加新字段的任务,而这个新字段的名字是name_of_new_field,其值是“new_field”,注意这里对引号需转义处理。
图2.11 更新tag后的索引数据
//代码段2.29:通过 Update API修改文档结构并增加新的字段 curl-XPOST http://localhost:9200/weibo/wb/5/_update-d'{ "script": "ctx._source.name_of_new_field=\"new_field\"" }'
代码段2.30表示在使用UpdateAPI时,如果该记录(即指定的id号,此例中是7)不存在,则通过参数体中的upsert创建这个文档,并且加入新的字段(其名为counter,其值为1);如果有该记录(即指定的id号,例子中是7),就把指定的字段like增加4(在代码中的params中表明拟增加的偏移量)。
//代码段2.30:通过 Update API修改 document结构 curl-XPOSThttp://localhost:9200/weibo/wb/7/_update-d'{ "script": { "inline": "ctx._source.like+=params.count", "lang":"painless", "params": { "count":4 } }, "upsert": { "counter":1 } }'
2.7.4 基于POST方式批量获取文档
Elasticsearch支持一次操作多条记录。如下代码段2.31可返回记录的id号为5和7的记录信息,注意语句中的_mget参数的使用。
//代码段2.31:基于 POST方式批量获取文档 curl-XPOSThttp://localhost:9200/weibo/wb/_mget? -d'{ "docs": [ { "_index": "weibo", "_type": "wb", "_id": "5" }, { "_index": "weibo", "_type": "wb", "_id": "7" } ] }'
针对代码段2.31的示例返回结果如图2.12所示。
图2.12 基于POST方式批量获取文档数据
也可使用_source过滤器。代码段2.32演示了相应方法。
//代码段2.32:使用_source过滤器获取文档 curl-XPOST curl'localhost:9200/_mget? pretty'-d'{ "docs": [ {"_index": "weibo", "_type": "wb", "_id": "3", "_source": false } ] }'
针对上述语句的示例返回值如下:
{ "docs": [{ "_index": "weibo", "_type": "wb", "_id": "3", "_version":2, "found": true }] }