はてだBlog(仮称)

私的なブログど真ん中のつもりでしたが、気づけばWebサイト系のアプリケーション開発周りで感じたこと寄りの自分メモなどをつれづれ述べています。2020年6月現在、Elasticsearch、pandas、CMSなどに関する話題が多めです。...ですが、だんだんとより私的なプログラムのスニペット置き場になりつつあります。ブログで述べている内容は所属組織で販売している製品などに関するものではなく、また所属する組織の見解を代表するものではありません。

Elasticsearch気になったこと逆引きメモ

はじめに

Elasticsearchで、システム管理・環境設計周りの話で、こんなことできるのかなみたいな気になったものを書き出して、確認した内容をメモる。

調べたい事項の備忘録も兼ねているので、で、結局どうなのさというものが常に残る可能性あり。

記事の拙さはまだしも、エターナル未完成なのにネット公開するのは心苦しいが、サイトパワーを考えると実害はないと思って勝手に納得・言い訳しておくことにする。

インデックス更新

Mappingで各フィールドをワイルドカードなどで一括設定できるか?

ここでは、CoCの悪いところかどうかみたいなのはおいておこう。 "*_str"はすべてstringとする、みたいなことが可能かどうか。 設計の初期には、こういうことも必要かもしれない。

Mappingで定義を使いまわせるか?

意味があるかは別。気になりません?

元のドキュメントでは、苗字と名前で別項目だが、検索フィールドとしては、氏名を一体にしたものとしたい

copy_toが良いと思われます。

www.elastic.co

検索のビューアーや設計時にデータの調べ物を行う際のおすすめは?

今だったら、kibanaかちょっと用途が限られるがFessのような気がする。 elasticsearch-headは老舗なのかな。

typeのメタフィールドは? そもそも予約されているフィールド名をなんて言う。

タイトルでネタバレしているが、Meta-fieldsと言うらしい。 Meta-fieldsは、index、type、id、sourse の全部で4つなのかな。

index設計のコツは。更新性能、コーディングが楽、拡張性、検索の精度、検索の性能、サービス無停止、インデックス再作成、バージョンアップ、 これらのトレードオフは?

テーマが大きいな....

Dyanamic Mapping のヒミツ

性能以外で課題になるところや、便利なところ。TIPS。

既存のMappingを更新できるのか。

できないらしい。Indexの再作成となる。要参考文献。

※typeはそのうちなくなるそう。と言っても、従来で言うところのtypeが別のドキュメントは、それぞれ対応する別のindexで管理せよという話。

元のドキュメントのある項目を複数のアナライザーを適用するなど派生項目として定義できるか?

Multi-fields ということで、できるそうです。

www.elastic.co

なお、これを利用して、一度定義したMappingを変更する...相当にできるという話もありますが、試していません。 また、できたとしてそれが既存の検索にどう作用するかは確認していないです。

kobitosan.hatenablog.com

Webページクロール用のおすすめのクローラーは何?

クローリングのスケジュールやトリガーは別に管理できる/するとする。

営業時間の検索

日時の範囲などはもちろんよろしく検索できて素晴らしい。

qiita.com

ここでは月曜10:00〜20:00のようなBussiness Hour風の元データの検索の話。

検討中。特にシンタックスシュガーとか専門のクエリはなさそうなので素直に実装かな。

kuromoji-neologdはAWSのElasticsearch Serviceでつかえるのか。

使えなさそうだが、確認中。

JSON-LD を楽チンに取り込む定石はあるのか?

確認中。

対応するデータ型は?

  1. Core datatypes
  2. Complex datatypes
  3. Geo datatypes
  4. Specialised datatypes

これらをキーワードに公式を検索するのがスジ。

ひとまず、日本語では、こちらのページの「様々な種類のデータ型に対応可能」セクションを参照させていただいた。

dev.classmethod.jp

バルクロードはあるのか?

あります。

SQLのUPDATE文で複数行を一括更新できるがその類のものはあるか?

Delete By Query API、 Update By Query API というものがある。

www.elastic.co

検索関連

ネストされたフィールド名を検索対象に指定するには? (続きあり)

どこかで、"xxx.yyy"のように指定できると見たような。

では配列だったらどうするのというところもきになる。

ギモンのネストというのは用語が正しくないかもしれない。

文字通りNestというところでESの世界で出てくるのが、Nested Fieldという概念があるらしい。

先に、Nested Fieldというのを確認することとしよう。

tkrtkhsh.hatenablog.com

... と見ていると、Objectデータ型という考え方もあるらしい。

ちゃんとデータ型の種類を先に確認した方が良いような気がしてきた....

dev.classmethod.jp

ちなみに、階層を無視して、あいまいなフィールド名(末端のフィールド名)でもルックアップできるとのこと。  (ただし最初に見つけたもの限定) http://blog.johtani.info/blog/2015/07/08/great-mapping-refactoring-ja/

結局のところ、次のとおり、"xxx.yyy"で指定できるが、そもそもどのようなドキュメントが登録されているかというところを抑えること。

// インデックスにドキュメントを登録
PUT my_index/_doc/8
{
  "manager": {
    "age":     30,
    "name": {
      "first": "John",
      "last":  "Smith"
    }
  }
}

// 検索
GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "manager.name.first": "John"
          }
        },
        {
          "match": {
            "manager.name.last": "Smith"
          }
        }
      ]
    }
  }
}

// 検索結果
{
  "took": 1,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.5753642,
    "hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.5753642,
        "_source": {
          "region": "US",
          "manager": {
            "age": 30,
            "name": {
              "first": "John",
              "last": "Smith"
            }
          }
        }
      }
    ]
  }
}

配列はうまく扱えるのか。

階層化されたドキュメントをどう検索するか以前として、

 PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

みたいなのは、John Smith、Alice Whiteの塊になるように、mappingで「"type": "nested"」を指定すると良い。 (これを指定しないと、デフォルトでは John、Alice、Smith、Whiteの4 つのワードにばらばらで保持されるので、John Aliceを検索するのが難しい。)

www.elastic.co

スクリプトの基本的な構文

スコアリングのための例などが多く、他の知識が求められる複雑な例が多いので混乱しやすい気がした。

基本的な例がころがっていないかなーと探したところ、公式のこの例が一番シンプルな気がした。

www.elastic.co

クエリビルダーのための良いライブラリはないのかな?

日本だと、rubyおよびRailsはgemやらプラグインやらちらちら目にする。

知りたいのは、JavaJavaScript(nodejs)、Python

探しているクエリビルダー的なものかは別として、Pythonの場合の公式サイト。

elasticsearch-py | Elastic

dev.classmethod.jp

Python Elasticsearch Client — Elasticsearch 6.3.1 documentation

検索の際に日付を楽チンに扱えるか。例えば、「N日前」のような指定ができるか。

Date Math という考えかたがある。

www.elastic.co

複数のクエリを一括実行できないか?

Multi Search APIというのがあります。

www.elastic.co

普通の検索結果画面を実現するにはさほど使わないような気がするが、バッチ的なものやアドホックダッシュボードを実現する場合などは便利そう。

aggregationsをいわゆるファセットとして使うが、ファセット自体は絞り込み前の選択肢をそのまま残したい

まず何を言っているかというと、

  1. 商品検索で、キーワードで家族向けで検索しました。
  2. 検索結果にaggsで価格帯ごとに絞り込み条件を提示しました。
  3. ユーザは5000円クラスで絞り込みました。
  4. 検索結果は、家族向けの5000円クラスですが、ファセット部分は、2000円、3000円、5000円、6000円(つまり、1の検索結果に対応するaggs)を表示し、5000円が選択状態になるようにする。

という話。

この場合は2回の別クエリを発行しなければならんのかな〜と思われたが、1パスのクエリで済ませられる。 具体的には、post_filterを使う。

ruby-rails.hatenadiary.com

一応、データの仕込みも含めた、ver6.4での例

// 仕込み1
PUT reviews
{
    "mappings" : {
      "review" : {
        "properties" : {
          "item_code" : {
            "type" : "text"
          },
          "comment" : {
            "type" : "text"
          },
          "rate" : {
            "type" : "integer"
          }
        }
      }
    }

}

// 仕込み2
POST review/_doc
{
          "item_code" : "0001",
          "comment" : "This is a comment1",
          "rate" : 5
}

POST review/_doc
{
          "item_code" : "0001",
          "comment" : "This is a message1",
          "rate" : 10
}


POST review/_doc
{
          "item_code" : "0002",
          "comment" : "This is a message2",
          "rate" : 200
}


// 検索 ※通常、matchの並びにいるfilterが、post_filterでaggsの並びに配置。
POST review/_search?typed_keys
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "comment": "This is"
          }
        }
      ]
    }
  },
  "aggregations": {
    "rate_average": {
      "avg": {
        "field": "rate"
      }
    },
    "rate_terms": {
      "terms": {
        "field": "rate"
      }
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "item_code": "0002"
          }
        }
      ]
    }
  }
}





検索クエリのJSONをテンプレート化できないのか?

なんと、mustacheが使える。

www.elastic.co

しかも、Multi Search APIの Search Template版もある。

テンプレート化が特に有効そうだ。

www.elastic.co

Elasticsearchをバックエンドにしている検索サイトのURL設計

管理・運用

設定などはJSONで階層化されているのでそれはそれでわかりやすいが、EXCEL仕様書などに実績を貼り付けたいのでプロパティ形式で参照できるか?→ Flat Settings

GET twitter/_settings?flat_settings=true

などとやると

 "index.number_of_replicas": "1",
 "index.number_of_shards": "1",
 "index.creation_date": "1474389951325",

のような回答が返ってくるらしい。

(推奨の)管理ツール的なものは?

dev.classmethod.jp

version について

Versioning とあるが、何か便利そうだけどスマートな使い方が想像力不足で思いつかない。

www.elastic.co

↓の楽観的並行性制御のあたりかな。ありがとうございます。

第3回 Elasticsearch 入門 ドキュメント管理は意外と高度なことができる | DevelopersIO

ElasticStackでのユースケースなどでありそうな例として、古いログのインデックスは集計済みにして退避する(ただしこの集計済みのデータに対して検索は行う)とか、検索ユースケースにおいてサマリ済みの過去検索用のインデックスを分けて管理するといったことに適した仕掛けはないか?

あります。

こちらを参考にさせてもらいました。

qiita.com

GEO検索で「測地系」の違いはどうする?

まず、測地系とはというところで、下記を参考にさせていただいた。

qiita.com

次に、昔どこかで見かけた(ような記憶がある)Elasticsearchでの測地系指定の例を再度ググったけど見つけられず。

仕方がないので、公式に確認。

www.elastic.co

特に記述がないなあ。

www.elastic.co

Geo-Shapeの方は、

WGS-84 coordinates only.

とかいてあるように見える。

裏返すと、Geo-Pointはいろいろ対応しているのではないかと思うが...。

続きはまた今度。(@ 2018/11/22 )

ログなどのストックにElasticsearchを使う場合など、インデックス名に日付を保持するような管理はできるのか?

できます。 Date math support in index names

www.elastic.co