Elasticsearch#
Elasticsearch は、Lucene ベースの分散型検索エンジンであり、大量のデータを高速かつ正確に検索することができるエンジンです。そのクエリ言語 DSL は非常に強力であり、bool、match、term、must、should などさまざまなクエリ方法をサポートしており、集計クエリや plainless スクリプトも実行することができます。今日は、これらの文法とテクニックを使用して ES で必要なデータを見つける方法を学びましょう。たとえば、特定の顧客の注文履歴を見つけたり、特定の期間内の販売データを確認したりする場合、ES を使用すると簡単に処理できます。要するに、ES は非常に便利であり、これらの文法とテクニックを学ぶことで、データの追加、削除、変更、検索がより簡単になります!(他の人のクエリ DSL を変更する必要はありません)
- クエリ文法
ES のクエリ文法には、次の主要な部分があります:クエリタイプ、クエリ条件、フィルタ条件、ソート条件です。クエリタイプには、match、term、bool などがあり、クエリ条件は検索するフィールドとキーワードを指定し、フィルタ条件は検索結果をフィルタリングするために使用され、ソート条件は検索結果をソートするために使用されます。
1.1 match クエリ
match クエリは、ES で最も一般的に使用されるクエリ方法であり、指定したフィールド内のドキュメントで指定したキーワードを検索します。たとえば、「Elasticsearch」というキーワードを含むドキュメントを検索するには、次の DSL 文を使用します:
{
"query": {
"match": {
"content": "Elasticsearch"
}
}
}
ここで、「content」は検索するフィールド名であり、「Elasticsearch」は検索するキーワードです。複数のフィールドでキーワードを検索する場合は、次の文を使用します:
{
"query": {
"multi_match": {
"query": "Elasticsearch",
"fields": ["title", "content"]
}
}
}
1.2 term クエリ
term クエリは、特定のフィールドの値を正確に一致させるために使用されます。たとえば、「status」フィールドの値が「published」のドキュメントを検索するには、次の DSL 文を使用します:
{
"query": {
"term": {
"status.keyword": "published"
}
}
}
注意する必要があるのは、keyword タイプのフィールドを検索する場合、フィールド名の後ろに「.keyword」を追加する必要があるということです。
1.3 bool クエリ
bool クエリは、複数のクエリ条件を組み合わせ、must、should、must_not の 3 つの論理関係をサポートするために使用されます。たとえば、「title」フィールドに「Elasticsearch」というキーワードが含まれ、「status」フィールドの値が「published」のドキュメントを検索するには、次の DSL 文を使用します:
{
"query": {
"bool": {
"must": [
{ "match": { "title": "Elasticsearch" } },
{ "term": { "status.keyword": "published" } }
]
}
}
}
注意する必要があるのは、must と should を同時に使用することはできないということです。:)
- 集計クエリ
集計クエリは、ES で非常に便利な機能であり、クエリ結果をグループ化、統計、ソートなどの操作を行うことができます。ES は、terms、range、date_histogram など、さまざまな集計方法をサポートしています。
2.1 terms 集計
terms 集計は、特定のフィールドをグループ化して統計するために使用されます。たとえば、「category」フィールドをグループ化して統計するには、次の DSL 文を使用します:
{
"aggs": {
"group_by_category": {
"terms": {
"field": "category.keyword"
}
}
}
}
ここで、「group_by_category」は集計の名前であり、「category.keyword」は集計するフィールド名です。
2.2 range 集計
range 集計は、特定のフィールドの範囲統計を行うために使用されます。たとえば、「price」フィールドの範囲統計を行うには、次の DSL 文を使用します:
{
"aggs": {
"price_range": {
"range": {
"field": "price",
"ranges": [
{ "to": 50 },
{ "from": 50, "to": 100 },
{ "from": 100 }
]
}
}
}
}
ここで、「price_range」は集計の名前であり、「price」は集計するフィールド名であり、「ranges」は統計する範囲を指定しています。
- 上級テクニック
基本的なクエリと集計操作に加えて、ES は painless スクリプト、ネストされたクエリなど、いくつかの上級テクニックもサポートしています。
3.1 painless スクリプト
painless スクリプトは、ES に組み込まれたスクリプト言語であり、Java に似た構文をサポートし、豊富な API インターフェースを提供しています。painless スクリプトを使用することで、より複雑なデータ処理や計算操作を実現することができます。たとえば、クエリ結果に新しいフィールド「score」を追加するには、次の DSL 文を使用します:
{
"query": {
"match_all": {}
},
"script_fields": {
"score": {
"script": {
"lang": "painless",
"source": "_score * doc['price'].value"
}
}
}
}
ここで、「_score」はドキュメントのスコアを表し、「doc ['price'].value」は「price」フィールドの値を取得することを示しています。
3.2 ネストされたクエリ
ネストされたクエリは、ドキュメント内のネストされたサブドキュメントをクエリするために使用されます。たとえば、ブログシステムでは、各記事に複数のコメントが含まれる場合があります。各コメントは、記事にネストされたサブドキュメントです。すべてのコメントに「Elasticsearch」が含まれる記事をクエリするには、次の DSL 文を使用します:
{
"query": {
"nested": {
"path": "comments",
"query": {
"match": {
"comments.content": "Elasticsearch"
}
}
}
}
}
ここで、「comments」はサブドキュメントの名前であり、「content」はクエリするサブドキュメントのフィールド名です。
- 注意事項
ES を使用して検索、追加、削除、変更を行う際には、次の点に注意する必要があります:
- keyword タイプのフィールドを検索する場合、フィールド名の後ろに「.keyword」を追加する必要があります。
- ネストされたクエリを使用する場合、nested クエリを使用する必要があります。
- must と should を同時に使用することはできません。
- painless スクリプトを使用する場合、セキュリティとパフォーマンスの問題に注意する必要があります。
要するに、ES を使用して検索、追加、削除、変更を行う際には、関連する DSL 文法とテクニックを熟知し、可能な問題を回避するために注意する必要があります。この記事がお役に立てれば幸いです!
- 参考資料
上記の ES のバージョンは 6.8.17 ですが、私は ES 7 のバージョンも使用しており、ベクトルタイプのフィールドの検索をサポートしています。将来的には、別の記事でその詳細を記録します。