Elasticsearch の基本操作 - RESTful 操作
1.RESTfulの紹介
REST は、一連のアーキテクチャ上の制約と原則を指します。これらの制約と原則を満たすアプリケーションまたは設計は RESTful です。Web アプリケーションの REST の最も重要な原則は、クライアントとサーバー間の対話が要求間でステートレスであることです。クライアントからサーバーへのすべてのリクエストには、リクエストを理解するために必要な情報が含まれている必要があります。リクエスト間の任意の時点でサーバーが再起動した場合、クライアントには通知されません。さらに、ステートレスなリクエストには、利用可能な任意のサーバーで応答できます。これは、クラウド コンピューティングなどの環境に最適です。クライアントは、パフォーマンスを向上させるためにデータをキャッシュできます。
サーバー側では、アプリケーションの状態と機能をさまざまなリソースにグループ化できます。リソースは、クライアントに公開される興味深い概念エンティティです。リソースの例としては、アプリケーション オブジェクト、データベース レコード、アルゴリズムなどがあります。各リソースは URI (Universal Resource Identifier) を使用して一意のアドレスを取得します。すべてのリソースは、クライアントとサーバー間で状態を転送するための統一されたインターフェイスを共有します。GET、PUT、POST、DELETE などの標準の HTTP メソッドが使用されます。
RESTful Web サービスでは、各リソースにアドレスがあります。リソース自体はすべてメソッド呼び出しのターゲットであり、メソッド リストはすべてのリソースで同じです。これらのメソッドは標準であり、HTTP GET、POST、PUT、DELETE、および場合によっては HEAD と OPTIONS が含まれます。簡単に理解すると、インターネット上のリソースにアクセスする場合は、リソースが配置されているサーバーにリクエストを送信する必要があり、リクエストの本文にはリソースのネットワーク パスとリソースに対する操作が含まれている必要があります (さらに、削除、変更、およびクエリ)。
2. クライアントのインストール
ブラウザーを介して直接 Elasticsearch サーバーに要求を送信する場合、送信される要求に HTTP 標準メソッドを含める必要があり、HTTP のほとんどの機能は GET および POST メソッドのみをサポートします。そのため、クライアント アクセスを容易にするために、Postman (中国語をサポートしていませんが、比較的多くの人が使用しています)、Apipost (中国語によって作成された)、Apifox (中国語によって作成された) などの api デバッグ ツールを使用できます。
ポストマン:https://www.postman.com/downloads/
アピポスト:https://www.apipost.cn//
アピフォックス:https://www.apifox.cn/
Postman: シンプルで明確なインターフェイス、便利で高速な操作、非常にユーザーフレンドリーなデザインを備えた、昔ながらの強力な Web ページ デバッグ ツールです。ただし、中国語はサポートされておらず、中国人向けの中国語パッケージもバージョン 9.12.2 で停止していますhttps://github.com/hlmd/postman-cn
Apipost&Apifox: 中国人が作ったもので、中国語に対応しており、個人版は無料です. 基本的には Postman が持っているものを持っています. また、コラボレーションをサポートし、Web バージョンをサポートし、さまざまなドキュメントをエクスポートし、さまざまな言語でコードを生成します. 主な理由は、サーバーが中国にあり、ワークスペースをリモート エンドに同期できることです.ただし、郵便配達員サーバーは海外にあり、アクセス速度が非常に遅いです.登録してログインしないようにしてください。非常に立ち往生。
3. データ形式
Elasticsearch は、データの一部がドキュメントであるドキュメント指向のデータベースです。
Elasticsearch にドキュメント データを格納する概念と、リレーショナル データベース MySQL にデータを格納する概念の間には類似性があり、
ES のインデックスはライブラリと見なすことができ、タイプはテーブルに相当し、ドキュメントは行に相当します。テーブル。ここでは、タイプの概念が徐々に弱体化されており、Elasticsearch 6.X では、インデックスには 1 つのタイプしか含めることができませんでしたが、Elasticsearch 7.X では、タイプの概念が削除されました。
6 ユーザー情報の一部など、ドキュメントのシリアル化形式として JSON を使用します。
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"birthDate": "1990/05/01",
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
4.HTTP操作
4.1 インデックス操作
インデックスを作成
リレーショナル データベースと比較すると、インデックスの作成はデータベースの作成に相当します
PUT リクエストを ES サーバーに送信します: http://127.0.0.1:9200/shopping
{
"acknowledged"【响应结果】: true, # true 操作成功
"shards_acknowledged"【分片结果】: true, # 分片操作成功
"index"【索引名称】: "shopping"
}
# 注意:创建索引库的分片数默认 1 片,在 7.0.0 之前的 Elasticsearch 版本中,默认 5 片
インデックスが繰り返し追加されると、エラー メッセージが返されます。
単一のインデックスを表示する
GET リクエスト: http://127.0.0.1:9200/shopping
でインデックスを表示 ES サーバーに送信されるリクエスト パスは、インデックスの作成と一致しています。しかし、HTTP メソッドには一貫性がありません。ここで
RESTful の意味を体験できます.
リクエストの後、サーバーは次のように応答します:
{
"shopping"【索引名】: {
"aliases"【别名】: {
},
"mappings"【映射】: {
},
"settings"【设置】: {
"index"【设置 - 索引】: {
"creation_date"【设置 - 索引 - 创建时间】: "1614265373911",
"number_of_shards"【设置 - 索引 - 主分片数量】: "1",
"number_of_replicas"【设置 - 索引 - 副分片数量】: "1",
"uuid"【设置 - 索引 - 唯一标识】:"eI5wemRERTumxGCc1bAk2A",
"version"【设置 - 索引 - 版本】: {
"created": "7080099"
},
"provided_name"【设置 - 索引 - 名称】: "shopping"
}
}
}
}
すべてのインデックスを見る
GET リクエスト: http://127.0.0.1:9200/_cat/indices?v
ここでのリクエスト パスの _cat は表示を意味し、indexs はインデックスを意味するため、全体的な意味は、現在の ES サーバー内のすべてのインデックスを表示することです。 MySQL サーバーの応答結果でテーブルを表示する感じは次のとおりです。
ヘッダ | 意味 |
---|---|
健康 | 現在のサーバーのヘルス ステータス: |
緑(クラスター完成) 黄(一点正常、クラスター未完成) 赤(一点異常) | |
スターテス | インデックスオープン、クローズ状態 |
索引 | 索引名 |
uuid | インデックス背番号 |
で | プライマリ シャードの数 |
担当者 | 部数 |
docs.count | 利用可能なドキュメントの数 |
docs.deleted | 文書の削除状況 (tombstone) |
store.size | プライマリ シャードとセカンダリ シャードの全体のサイズ |
pri.store.size | プライマリ シャードが占めるスペース |
インデックスを削除
DELETE リクエスト: http://127.0.0.1:9200/shopping
インデックスに再度アクセスすると、サーバーは応答を返します: インデックスは存在しません
4.2 ドキュメント操作
ドキュメントを作成する
ここにあるドキュメントはリレーショナル データベースのテーブル データと比較でき、追加されたデータ形式は JSON 形式です。
POST リクエスト: http://127.0.0.1:9200/shopping/_doc
リクエスト本文の内容: (リクエスト本文が存在する必要があります。存在しない場合、エラー メッセージが返されます)
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":3999.00
}
ここで要求を送信する方法は、PUT ではなく POST でなければなりません。そうしないと、同様の 405 エラーが発生します。
勉強中に Apipost6.x 版にいくつか問題が見つかったので、5.x 版に切り替えました。インターフェイスは上のスクリーンショットとは異なる場合があります。
この問題の原因は、Apipost6.x バージョンが応答コード 201 をリダイレクトし、ES サーバーが Get 要求を受信することです。エラーメッセージは上に表示されています。公式に報告済みで、以降のバージョンで修正される予定です。
国内生産はまだまだ頑張る必要があります。
通常のサーバー応答の結果は次のとおりです。
{
"_index"【索引】: "shopping",
"_type"【 类型-文档 】: "_doc",
"_id"【唯一标识】: "w_WoYoIBNKuSN7cz5FHR", #可以类比为 MySQL 中的主键,随机生成
"_version"【版本】: 1,
"result"【结果】: "created", #这里的 created 表示创建成功
"_shards"【分片】: {
"total"【分片 - 总数】: 2,
"successful"【分片 - 成功】: 1,
"failed"【分片 - 失败】: 0
},
"_seq_no": 0,
"_primary_term": 1
}
上記のデータが作成された後、データの一意の識別子 (ID) が指定されていないため、デフォルトでは、ES サーバーによってランダムに生成されます。
一意の識別子をカスタマイズする場合は、作成時に指定する必要があります: http://127.0.0.1:9200/shopping/_doc/1
ここで注意: データを追加するときにデータの主キーを指定すると、リクエスト メソッドPUTすることもできます
単一のドキュメントを表示する
ドキュメントを表示するときは、ドキュメントの一意の識別子を指定する必要があります。これは、MySQL のデータの主キー クエリと同様です。
GET リクエスト: http://127.0.0.1:9200/shopping/_doc/1
{
"_index"【索引】: "shopping",
"_type"【文档类型】: "_doc",
"_id": "1",
"_version": 2,
"_seq_no": 2,
"_primary_term": 2,
"found"【查询结果】: true, # true 表示查找到,false 表示未查找到
"_source"【文档源信息】: {
"title": "华为手机",
"category": "华为",
"images": "http://www.gulixueyuan.com/hw.jpg",
"price": 4999.00
}
}
ドキュメントを修正する (フル リビジョン)
新しいドキュメントを追加するのと同じように、同じ URL アドレス リクエストを入力します。リクエスト ボディが変更されると、元のデータ コンテンツが上書きされます。
POST/PUT リクエスト: http://127.0.0.1:9200/shopping/_doc/1
{
"title":"小米手机",
"category":"小米",
"images":"http://www.gulixueyuan.com/xm.jpg",
"price":2999.00
}
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 2,
"result"【结果】: "updated", # updated 表示数据被更新
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 2,
"_primary_term": 2
}
フィールドの変更 (ローカル変更)
データを変更する場合、特定のデータ POST リクエストの部分的な情報のみを変更することもできます
: http://127.0.0.1:9200/shopping/_update/1
リクエスト本文の内容は次のとおりです。
{
"doc": {
"price":3000.00
}
}
一意の識別に従って、文書データを照会し、文書データが更新されました
ドキュメントを削除
ドキュメントを削除しても、ディスクからすぐに削除されるわけではなく、削除済み (廃棄) としてマークされるだけです。
削除リクエスト: http://127.0.0.1:9200/shopping/_doc/1
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version"【版本】: 4, #对数据的操作,都会更新版本
"result"【结果】: "deleted", # deleted 表示数据被标记为删除
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 4,
"_primary_term": 2
}
削除後、現在の文書情報を問い合わせる
存在しない文書を削除した場合
{
"_index": "shopping",
"_type": "_doc",
"_id": "1",
"_version": 1,
"result"【结果】: "not_found", # not_found 表示未查找到
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 5,
"_primary_term": 2
}
ドキュメントを条件付きで削除する
通常は、文書の一意の識別子に従ってデータを削除しますが、実際の運用では、条件に応じて複数のデータを削除することもできます。
- 最初に複数のデータをそれぞれ追加します。
{
"title": "小米手机",
"category": "小米",
"images": "http://www.gulixueyuan.com/xm.jpg",
"price": 4000
}
{
"title":"华为手机",
"category":"华为",
"images":"http://www.gulixueyuan.com/hw.jpg",
"price":4000.00
}
POSTリクエスト: http://127.0.0.1:9200/shopping/_delete_by_query
リクエスト本文の内容は次のとおりです。
{
"query":{
"match":{
"price":4000.00
}
}
}
{
"took"【耗时】: 6,
"timed_out"【是否超时】: false,
"total"【总数】: 1,
"deleted"【删除数量】: 1,
"batches": 1,
"version_conflicts": 0,
"noops": 0,
"retries": {
"bulk": 0,
"search": 0
},
"throttled_millis": 0,
"requests_per_second": -1,
"throttled_until_millis": 0,
"failures": []
}
4.3 マッピング操作
インデックス ライブラリを使用すると、データベース内にデータベースを持つことと同じになります。
次に、データベース (データベース) のテーブル構造 (テーブル) に似たインデックス ライブラリ (インデックス) にマッピングを作成する必要があります。データベース テーブルを作成するには、フィールド名、型、長さ、制約などを設定する必要があります。インデックス ライブラリの場合も同様で、どのフィールドがこの型の下にあり、各フィールドにどのような制約情報があるかを知る必要があります。 . これはマッピングと呼ばれます。
マッピングを作成する
- index Student
PUT リクエストを作成します: http://127.0.0.1:9200/student - マッピング
PUT リクエストを作成します: http://127.0.0.1:9200/student/_mapping
マッピング データの説明: - フィールド名: 自由に入力し、以下の多くの属性を指定します。例: タイトル、サブタイトル、画像、価格
- タイプ: タイプ。Elasticsearch でサポートされているデータ タイプは非常に豊富で、重要なものをいくつか挙げます。
- String 型は、次の 2 つの型に分けられます。
- テキスト: 分離可能な単語
- キーワード: 分割不可。データは完全なフィールドとして照合されます
- 数値型: 数値型で、2 つのカテゴリに分けられます
- 基本データ型: long、integer、short、byte、double、float、half_float
- 浮動小数点数の高精度型: scaled_float
- 日付: 日付タイプ
- 配列:配列型
- オブジェクト: オブジェクト
- String 型は、次の 2 つの型に分けられます。
- index: インデックスを作成するかどうか。デフォルトは true です。つまり、構成なしですべてのフィールドにインデックスが作成されます。
- true: フィールドは索引付けされ、検索に使用できます
- false: フィールドは索引付けされず、検索に使用できません
- store: データを個別に保存するかどうか。デフォルトは false です。
元のテキストは _source に保存されます。デフォルトでは、他の抽出されたフィールドは個別に保存されず、_source から抽出されます。もちろん、"store": true を設定する限り、特定のフィールドを個別に保存することもできます. 個別に保存されたフィールドを取得することは、_source から解析するよりもはるかに高速ですが、より多くのスペースも占有するため、ベースにする必要があります。ビジネスが設定する必要がある実際の状況について。 - アナライザー: ワード ブレーカー、ここの ik_max_word は ik ワード ブレーカーを使用するためのものです。後で学習する特別な章があります
地図を見ます
GET リクエスト: http://127.0.0.1:9200/student/_mapping
インデックス マップの関連付け
PUT リクエスト: http://127.0.0.1:9200/student1
{
"settings": {
},
"mappings": {
"properties": {
"name": {
"type": "text",
"index": true
},
"sex": {
"type": "text",
"index": false
},
"age": {
"type": "long",
"index": false
}
}
}
}
インデックス作成時のマッピングと関連付けに相当
4.4 高度なクエリ
Elasticsearch は、JSON に基づく完全なクエリ DSL を提供して、クエリを定義し
、データを定義します。
# POST /student/_doc/1001
{
"name":"zhangsan",
"nickname":"zhangsan",
"sex":"男",
"age":30
}
# POST /student/_doc/1002
{
"name":"lisi",
"nickname":"lisi",
"sex":"男",
"age":20
}
# POST /student/_doc/1003
{
"name":"wangwu",
"nickname":"wangwu",
"sex":"女",
"age":40
}
# POST /student/_doc/1004
{
"name":"zhangsan1",
"nickname":"zhangsan1",
"sex":"女",
"age":50
}
# POST /student/_doc/1005
{
"name":"zhangsan2",
"nickname":"zhangsan2",
"sex":"女",
"age":30
}
インデックス ライブラリ内のすべてのドキュメントを表示する
GET/POST リクエスト: http://127.0.0.1:9200/_search
指定したインデックスの下にあるすべてのドキュメントを表示する
GET/POST リクエスト: http://127.0.0.1:9200/student/_search
{
"took"【查询花费时间,单位毫秒】: 1,
"timed_out"【是否超时】: false,
"_shards"【分片信息】: {
"total"【总数】: 1,
"successful"【成功】: 1,
"skipped"【忽略】: 0,
"failed"【失败】: 0
},
"hits"【搜索命中结果】: {
"total"【搜索条件匹配的文档总数】: {
"value"【总命中计数的值】: 5,
"relation"【计数规则】: "eq" # eq 表示计数准确, gte 表示计数不准确
},
"max_score"【匹配度分值】: 1,
"hits"【命中结果集合】: [
... ...
]
}
}
条件一致クエリ
- パス スプライシング パラメータ クエリ (2 番目をお勧めします)
GET/POST リクエスト: http://127.0.0.1:9200/student/_search?q=name:zhangsan
パラメータ | 例証する |
---|---|
? | クエリ パラメータを追加するコード |
q | クエリの意味を示します |
名前 | クエリ フィールド名 |
- リクエストボディはパラメータクエリを運ぶ(推奨)
マッチマッチタイプのクエリ、クエリ条件は単語に分割され、クエリが実行され、複数のエントリ間の関係はまたは
GET/POST リクエスト: http://127.0.0.1:9200/shopping/_search
リクエストボディの内容は次のとおりです。
{
"query": {
"match":{
"name":"zhangsan"
}
}
}
フィールド一致クエリ
multi_match は、複数のフィールドでクエリできることを除いて、match と似ています。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"multi_match": {
"query": "zhangsan",
"fields": ["name","nickname"]
}
}
}
キーワード完全一致クエリ
用語クエリ、完全一致キーワード クエリ、クエリ条件の単語分割なし。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"term": {
"name": {
"value": "zhangsan"
}
}
}
}
複数キーワードの正確なクエリ
用語クエリは用語クエリと同じですが、照合する複数の値を指定できます。
このフィールドに指定された値のいずれかが含まれている場合、ドキュメントは mysql の場合と同様に条件を満たしています。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"terms": {
"name": ["zhangsan","lisi"]
}
}
}
クエリ フィールドを指定する
デフォルトでは、Elasticsearch は _source に保存されているドキュメントのすべてのフィールドを検索結果として返します。
一部のフィールドのみを取得したい場合は、_source フィルタリングを追加できます
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"_source": ["name","nickname"],
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
フィルター フィールド
渡すこともできます:
- includes: 表示するフィールドを指定します
- excludes: 表示したくないフィールドを指定します
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"_source": {
"includes": ["name","sex"],
"excludes": ["nickname"]
},
"query": {
"terms": {
"nickname": ["zhangsan"]
}
}
}
複合クエリ
bool
他のさまざまなクエリをmust
(must)、must_not
(must not)、should
(should)で組み合わせる
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "zhangsan"
}
}
],
"must_not": [
{
"match": {
"age": "40"
}
}
],
"should": [
{
"match": {
"sex": "男"
}
}
]
}
}
}
エラーの説明:
age はマッピングでインデックスを作成できず、表示できません。(次の範囲クエリも発生します)
これは、インデックス マッピングの作成時に age と sex のインデックスが false に設定されているためです。以下はエラーのスクリーンショットです。
If you want to test, it is recommended to re-build an index, and then set the index of the mapping association age and sex to true. 通常
の結果の戻り値は次のようになります。
範囲クエリ
範囲クエリは、指定された範囲内にある数値または時間を検索します。範囲クエリでは次の文字を使用できます
オペレーター | 例証する |
---|---|
gt | より大きい> |
ゲート | 以上 >= |
それ | より小さい< |
LTE | 以下 <= |
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"range": {
"age": {
"gte": 30,
"lte": 35
}
}
}
}
あいまいクエリ
検索用語に類似した用語を含むドキュメントを返します。
編集距離は、ある用語を別の用語に変換するために必要な 1 文字の変更の数です。これらの変更には次のものが含まれます。
- キャラクター変更(ボックス→キツネ)
- 文字消し(黒→欠け)
- 文字を挿入 (原文 → 病気)
- 隣接する 2 文字を入れ替える (act → cat)
類似した用語を見つけるために、あいまいクエリは、指定された編集距離内で検索用語のすべての可能なバリエーションまたは拡張のセットを作成します。次に、クエリは各拡張子の完全一致を返します。
あいまいさによって編集距離を変更します。デフォルト値の AUTO が一般的に使用され、単語の長さに応じて編集距離が生成されます。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"fuzzy": {
"name": {
"value": "zhangsan"
}
}
}
}
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"fuzzy": {
"name": {
"value": "zhangsan",
"fuzziness": 2
}
}
}
}
単一フィールドの並べ替え
sort を使用すると、さまざまなフィールドで並べ替えることができ、順序で並べ替え方法を指定できます。desc 降順、asc 昇順。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"match": {
"name": "zhangsan"
}
},
"sort": [
{
"age": {
"order": "desc"
}
}
]
}
マルチフィールドソート
age と _score を一緒にクエリしたいとします。マッチは最初に age でソートされ、次に関連性スコアでソートされます。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"match_all": {
}
},
"sort": [
{
"age": {
"order": "desc"
}
},
{
"_score": {
"order": "desc"
}
}
]
}
ハイライト クエリ
キーワード検索を実行すると、検索されたコンテンツ内のキーワードが異なる色で表示されます。これをハイライトと呼びます。
Elasticsearch では、クエリ内容のキーワード部分のラベルとスタイル (ハイライト) を設定できます。
一致クエリを使用しているときに、ハイライト属性を追加します。
- pre_tags: プレラベル
- post_tags: 投稿タグ
- fields: 強調表示する必要があるフィールド
- タイトル: タイトル フィールドを強調表示する必要があることをここで宣言します。後でこのフィールドに固有の構成を設定するか、空にすることができます。
GET リクエスト: http://127.0.0.1:9200/student/_search
{
"query": {
"match_all": {
}
},
"from": 0,
"size": 2
}
完全なクエリ
(通常、データ量が多いため、ページングと組み合わせて使用されます...)
GET/POST リクエスト: http://127.0.0.1:9200/student/_search
リクエスト ボディの内容は次のとおりです。
{
"query": {
"match_all":{
}
}
}
ページング クエリ
from: 現在のページの開始インデックス。デフォルトでは 0 から始まります。from = (pageNum - 1) * size
size: 各ページに表示される項目の数
GET/POST リクエスト: http://127.0.0.1:9200/student/_search
リクエストボディの内容は次のとおりです。
{
"query": {
"match_all": {
}
},
"from": 0,
"size": 2
}
集計クエリ
集計を使用すると、リレーショナル データベースのグループ化と同様に、ユーザーは es ドキュメントに対して統計分析を実行できます。もちろん、最大値、平均値など、他にも多くの集計があります。
- field max
GET リクエストの最大値を取る: http://127.0.0.1:9200/student/_search
{
"aggs": {
"max_age": {
"max": {
"field": "age"
}
}
},
"size": 0
}
- フィールドの最小値 min を取る
{
"aggs": {
"min_age": {
"min": {
"field": "age"
}
}
},
"size": 0
}
- フィールドを合計する
{
"aggs": {
"sum_age": {
"sum": {
"field": "age"
}
}
},
"size": 0
}
-
フィールドの平均値を取る
-
フィールドの値を重複排除してから合計を取る
-
州の集約