大数据搜索与挖掘及可视化管理方案 :Elastic Stack 5:Elasticsearch、Logstash、Kibana、X-Pack、Beats (第3版)
上QQ阅读APP看书,第一时间看更新

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
        }]
    }