# SearchAPIにおけるレスポンスデータの操作について

**URL:** <https://discuss.elastic.co/t/searchapi/200363>\
**Category:** 日本語による質問・議論はこちら\
**Created:** [September 20, 2019, 7:24am UTC](https://discuss.elastic.co/t/searchapi/200363 "2019-09-20T07:24:50Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sshota](https://avatars.discourse-cdn.com/v4/letter/s/f9ae1b/32.png) [@sshota](https://discuss.elastic.co/u/sshota)\
**Post date:** [September 20, 2019, 7:24am UTC](https://discuss.elastic.co/t/searchapi/200363/1 "2019-09-20T07:24:51Z")

</div>

お世話になります。

SearchAPIを使用して、Elasticsearchに貯めたデータを別システムへ連携しようとしています。

SearchAPIへのリクエストをプログラム化して、自動化するところまではできたのですが、  
レスポンスのデータを操作するところでつまずいています。

\_idを指定してリクエストしたところ、下記のレスポンスを取得できました。

> {  
> "took": 407,  
> "timed\_out": false,  
> "\_shards": {  
> "total": 1,  
> "successful": 1,  
> "skipped": 0,  
> "failed": 0  
> },  
> "hits": {  
> "total": {  
> "value": 1,  
> "relation": "eq"  
> },  
> "max\_score": 1,  
> "hits": [  
> {  
> "\_index": "testindex",  
> "\_type": "\_doc",  
> "\_id": "1234567890abcdefghijklmnopqrstuvwxyz0123",  
> "\_score": 1,  
> "\_source": {  
> "field1": "フィールド1",  
> "field2": "フィールド2",  
> ～

実際に連携先のシステムとして欲しいデータは、 hits.hits.\_source.field1～ 以降になるのですが  
このレスポンスからそのデータを取り出す際は、jsonの階層を掘っていって取得するしかないのでしょうか。

まだ検討を始めたばかりで、恐らくこういったシステム関連系のケースは  
よくあるかと存じますが、みなさんどのように実現されていますでしょうか。  
何かいい方法などありましたら、ご教示いただけますと幸いです。

どうぞよろしくお願いいたします。

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [September 21, 2019, 1:11pm UTC](https://discuss.elastic.co/t/searchapi/200363/2 "2019-09-21T13:11:04Z")

</div>

もちろん、レスポンスで返ってきたJSONを何とかするというのがシンプルかと思いますが、  
連携先のシステムが何で、どういう連携をしたいのかによって、選べる手段も変わってくるかと思います。  
今回は、それが明らかでないので、３つほど他のアプローチを紹介してみます。

1. Elasticsearch SQLを使う

> **[Elasticsearch SQL | ElasticsearchインデックスをSQLでクエリする](https://www.elastic.co/jp/elasticsearch/sql)**
>
> 速さと関連性スコアリング、水平スケーラビリティを備えたElasticsearchの全文検索を、使い慣れたSQLで実行できます。

詳細は上のページに書いてありますが、フォーマットをCSVやTSVに指定することができます。  
json以外のデータ取得方法が欲しいという場合は、この方法も検討できるかと思います。

例えば、このような感じです。

```auto

POST forum0920/_doc/1
{
  "field1": "hoge",
  "field2": "bar",
  "field3": "fuga"
}

POST _sql?format=tsv
{
  "query": """
  SELECT * FROM forum0920
  """
}

```

SELECTで取得する列名を具体的に書いてやれば、不要なフィールドも削ることができます。

```auto
POST _sql?format=tsv
{
  "query": """
  select 
  field1 as "フィールド1",
  field2 as "フィールド2"
  FROM forum0920
  """
}

```

1. LogstashのInputにElasticsearchを指定する

特定のインデックスに検索クエリを投げて、結果に対して何か（AWS S3に置く、ファイルに出力するなどなど）する場合には検討できるかもしれません。

> **[Elasticsearch input plugin | Logstash Reference \[8.11\] | Elastic](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-elasticsearch.html)**

1. 外部のツールと連携させる

CDataと何か他のETLツールを組み合わせるアプローチもあるかもしれません。

> **[Elasticsearch とのデータ連携に | Elasticsearch Drivers | CData Software Japan](https://www.cdata.com/jp/drivers/elasticsearch/)**
>
> Elasticsearch に帳票ツール、データベース、カスタムアプリケーションから連携！Elasticsearch データにあらゆるUI から簡単にアクセス。

* * *

（参考）

> [@ETL tool for ElasticSearch](https://discuss.elastic.co/t/etl-tool-for-elasticsearch/113803):
>
> Hi Guys, do you know any ETL tool where is possible to have a connector to ElasticSearch and get all data that i need? I was trying talend studio (big data) and oracle data integrator, but without results. if with this tools i cannot find a way to extract the data, Do you think that is better extract data and write it to a file and after use the ETL tool to load data from file? thank you

ご参考になれば幸いです。

---

<div class="post-metadata">

**Author:** ![sshota](https://avatars.discourse-cdn.com/v4/letter/s/f9ae1b/32.png) [@sshota](https://discuss.elastic.co/u/sshota)\
**Post date:** [September 26, 2019, 3:01am UTC](https://discuss.elastic.co/t/searchapi/200363/3 "2019-09-26T03:01:01Z")

</div>

ご回答ありがとうございます。  
頂いた候補から下記を試しているのですが、追加で2点ご教示頂けませんでしょうか。

> [@tsgkdt](#):
>
> 1. LogstashのInputにElasticsearchを指定する
> 
> 特定のインデックスに検索クエリを投げて、結果に対して何か（AWS S3に置く、ファイルに出力するなどなど）する場合には検討できるかもしれません。
> 
> [https://www.elastic.co/guide/en/logstash/current/plugins-inputs-elasticsearch.html](https://www.elastic.co/guide/en/logstash/current/plugins-inputs-elasticsearch.html)

1. InputにElasticsearchを指定した場合、起動し処理が終了したらLogstashがshutdownします。  
これは、Schedulerオプションが未指定であるため、" If no schedule is given, then the statement is run exactly once."の仕様に沿っている、という理解であっていますでしょうか。  
またそうである場合、できるならば常駐して、指定indexが更新された場合、その差分のみを取得するようにしたいのですが、そういったことはできますでしょうか。

2. Outputにemailプラグインを指定することを試みています。  
emailを送るということはできたのですが、Elasticsearch inputから取得したデータをJSON形式でメール本文に載せたいのですが、そのデータを取り出し方がわかりません。outputでどのように指定すればよいでしょうか。

本来の内容から一部外れている部分もありますが、  
ご回答頂けますと幸いです。

---

<div class="post-metadata">

**Author:** ![tsgkdt](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/tsgkdt/32/39151_2.png) [@tsgkdt](https://discuss.elastic.co/u/tsgkdt)\
**Post date:** [September 30, 2019, 12:42pm UTC](https://discuss.elastic.co/t/searchapi/200363/4 "2019-09-30T12:42:00Z")

</div>

常駐して、指定された条件に合致したらメールを送信する という用途でしたらWatcherでEmail Actionを検討するのはどうでしょうか？

[https://www.elastic.co/guide/en/elastic-stack-overview/current/watcher-getting-started.html](https://www.elastic.co/guide/en/elastic-stack-overview/current/watcher-getting-started.html)

Logstashの場合、inputでスケジュールを指定して（たとえば５分間隔で実行するなど）、  
クエリの中で、インデックス時間が今より５分前以上などとすれば、無理くりできなくもなさそうです。

```auto
  "query": {
    "range": {
      "timestamp": {
        "gte": "now-5m"
      }
    }
  }

```

Email送信ですが、特定のフィールド（例えば %{message}など）を指定することになるため、  
stdoutで出力されるようなjsonをメール本文にしたいというのは厳しそうです。

いずれにしましても、具体的に達成したい連携の目的や背景によって、選択できるものが変わってくるかと思います。  
他にも良いやり方があるかもわかりませんが、今のところこれぐらいしか思いつきません。

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [October 28, 2019, 12:42pm UTC](https://discuss.elastic.co/t/searchapi/200363/5 "2019-10-28T12:42:04Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
