springboot プロジェクトを手動で構築する 06-springboot は Elasticsearch とそのデモを統合します

目次


序文

Elasticsearch は、前例のない速度と規模でデータを探索できるリアルタイムの分散検索分析エンジンです。

他のものとは別に、倉庫の住所
ここに画像の説明を挿入


1. ElasticSearchとは何ですか?

ElasticSearch短い はビルドベースESであり、現在最も人気のある です, しかし、lucene の API は比較的複雑で、深い検索理論が必要です。実際のアプリケーションに組み込むのは困難です。Apache Lucene开源搜索引擎企业级搜索引擎Lucene本身就可以被认为迄今为止性能最好的一款开源搜索引擎工具包ES是采用java语言编写,提供了简单易用的RestFul API,开发者可以使用其简单的RestFul API,开发相关的搜索功能,从而避免lucene的复杂性

2. インストール

ダウンロードアドレス
https://www.elastic.co/cn/downloads/elasticsearch

2.1 Docker のインストール

1. フォルダーを作成する
-p 若建立目录的上层目录目前尚未建立,则会一并建立上层目录

mkdir -p ~/es/data ~/es/plugins

認可された

chmod 777 ~/es/data ~/es/plugins

2.ドッカーの起動

docker run -d --name es -p 9200:9200 -p 9300:9300 -v ~/es/data:/usr/share/elasticsearch/data -v ~/es/plugins:/usr/share/elasticsearch/plugins -e ES_JAVA_OPTS="-Xms256m -Xmx256m" -e "discovery.type=single-node" elasticsearch:7.14.0

3. ES
http://127.0.0.1:9200/にアクセスします。

2.2 キバナ

Kibana NavicatこれはターゲットですElasticsearch mysql。Kibana开源分析及可视化平台を使用できます查询、查看并与存储在ES索引的数据进行交互操作。Kibana を使用して高度な実行ができます。数据分析,并能以图表、表格和地图的形式查看数据。

ダウンロードアドレス
https://www.elastic.co/cn/downloads/kibana

2.2.1 Docker のインストール Kibana

1. フォルダーを作成する

mkdir -p ~/kibana/data ~/kibana/plugins ~/kibana/config

認可された

chmod 777 ~/kibana/data ~/kibana/plugins ~/kibana/config

2. 設定ファイルを変更する

vim ~/kibana/config/kibana.yml

添加如下代码段:
server.name: kibana
server.host: "0"
# 需要连接的地址
elasticsearch.hosts: [ "http://ip地址:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true

2.ドッカーの起動

docker run -d --privileged=true --name kibana -p 5601:5601 -v ~/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml -v ~/kibana/data:/usr/share/kibana/data -v ~/kibana/plugins:/usr/share/kibana/plugins kibana:7.14.0

3. kibana
http://127.0.0.1:5601/にアクセスします。

ここに画像の説明を挿入

3. 中心となる概念

索引

一个索引就是一个拥有几分相似特征的文档的集合たとえば、製品データのインデックス、注文データのインデックス、およびユーザー データのインデックスを作成できます。**,** また、このインデックス内のドキュメントのインデックス付け、検索、更新、削除を行う場合は、この名前を使用する必要があります。一个索引由一个名字来标识(必须全部是小写字母的)

地図

映射是定义一个文档和它所包含的字段如何被存储和索引的过程デフォルト構成では、ES は挿入されたデータに基づくことができます自动地创建mapping,也可以手动创建mappingマッピングには主にフィールド名、フィールドタイプなどが含まれます。

書類

文档是索引中存储的一条条数据。一条文档是一个可被索引的最小单元ES のドキュメントは軽量の JSON 形式データで表されます。

3.1 kibana と es の間の単純な対話

3.1.1 インデックス

作成

構文:PUT /索引名 ====> PUT /student_info
デフォルトでインデックスを作成すると、そのインデックスに対してバックアップ インデックスとプライマリ インデックスが作成されます。

# 创建索引 进行索引分片配置
PUT /student_info
{
    
    
  "settings": {
    
    
    "number_of_shards": 1, #指定主分片的数量
    "number_of_replicas": 0 #指定副本分片的数量
  }
}

ここに画像の説明を挿入

お問い合わせ

文法:GET /_cat/indices?v
ここに画像の説明を挿入

消去

構文: DELETE /索引名
DELETE /** はワイルドカードを表し、すべてのインデックスを表します
ここに画像の説明を挿入

3.1.2 マッピング

一般的なタイプ:

  1. 文字列型: キーワード キーワード キーワード、テキスト テキストの一部
  2. 数値タイプ: 整数長
  3. 10 進数型: float double
  4. ブール型: ブール型
  5. 日付の種類: 日付

複数のタイプ:作成するには、公式 Web サイトのドキュメントhttps://www.elastic.co/guide/en/elasticsearch/reference/7.15/mapping-types.htmlを参照してください。

PUT /student_info
{
    
    
  "settings": {
    
    
    "number_of_shards": 1,
    "number_of_replicas": 0
  }, 
  "mappings": {
    
    
    "properties": {
    
    
      "id":{
    
    
        "type": "text"
      },
      "name":{
    
    
        "type": "text"
      },
      "school":{
    
    
        "type": "text"
      },
      "age":{
    
    
        "type": "integer"
      },
      "createTime":{
    
    
        "type": "date"
      },
      "updateTime":{
    
    
        "type": "date"
      }
    }
  }
}

ここに画像の説明を挿入

クエリ - インデックスのマッピングを表示します。

文法:GET /索引名/_mapping
ここに画像の説明を挿入

3.1.3 文書

ドキュメントを追加

構文:POST /索引名/_doc/ドキュメント ID を自動的に生成する
構文:POST /索引名/_doc/文档idドキュメント ID=1 を生成する場合に指定します。ここに画像の説明を挿入

デフォルトの ID は、20 バイトのランダムな UUID (Universally Unique Identifier) で構成されます。ここに画像の説明を挿入

ドキュメントのクエリ:

文法:GET /索引名/_doc/文档id
ここに画像の説明を挿入

ドキュメントを更新します。

構文 1:
PUT /索引名/_doc/文档id { "属性名":"属性值" }ここに画像の説明を挿入

ここに画像の説明を挿入
说明: 这种更新方式是先删除原始文档,在将更新文档以新的内容插入。

文法 2:
POST /索引名/_doc/文档id/_update {"doc" : { "属性名" : "属性值" }}
ここに画像の説明を挿入ここに画像の説明を挿入
说明: 这种方式是将数据原始内容保存,再更新。

文書を削除します:

文法:DELETE /索引名/_doc/文档id
ここに画像の説明を挿入

バッチ操作

- 追加、削除、変更の一括操作

# 批量操作增删改
POST /student_info/_doc/_bulk
{
    
    
  "create": {
    
    
    "_index": "student_info",
    "_type": "_doc",
    "_id": "8"
  }
}
{
    
    
  "id": "8",
  "nickname": "王者荣耀"
}
{
    
    
  "update": {
    
    
    "_id": "7"
  }
}
{
    
    
  "doc": {
    
    
    "nickname": "赵琪1"
  }
}
{
    
    
  "delete": {
    
    
    "_id": "5"
  }
}

ここに画像の説明を挿入

- バッチフェッチ

GET /_mget
{
    
    
  "docs" : [
      {
    
    
          "_index" : "student_info",
          "_type" : "_doc",
          "_id" : "5"
      },
      {
    
    
          "_index" : "student_info",
          "_type" : "_doc",
          "_id" : "6"
      },
      {
    
    
          "_index" : "student_info",
          "_type" : "_doc",
          "_id" : "7"
      }
  ]
}

ここに画像の説明を挿入

3.2 高度なクエリ

ES はデータを取得する強力な方法を提供します。この種の取得メソッドは と呼ばれQuery DSL、 ES との対話をQuery DSL使用しますRest API传递JSON格式的请求体(Request Body)数据。このメソッドにより、丰富查询语法ES の取得が容易になります更强大,更简洁

テストデータ

# 1.创建索引 映射
PUT /products/
{
    
    
  "mappings": {
    
    
    "properties": {
    
    
      "title":{
    
    
        "type": "keyword"
      },
      "price":{
    
    
        "type": "double"
      },
      "created_at":{
    
    
        "type":"date"
      },
      "description":{
    
    
        "type":"text"
      }
    }
  }
}
# 2.测试数据
PUT /products/_doc/_bulk
{
    
    "index":{
    
    }}
  {
    
    "title":"iphone12 pro","price":8999,"created_at":"2020-10-23","description":"iPhone 12 Pro采用超瓷晶面板和亚光质感玻璃背板,搭配不锈钢边框,有银色、石墨色、金色、海蓝色四种颜色。宽度:71.5毫米,高度:146.7毫米,厚度:7.4毫米,重量:187克"}
{
    
    "index":{
    
    }}
  {
    
    "title":"iphone12","price":4999,"created_at":"2020-10-23","description":"iPhone 12 高度:146.7毫米;宽度:71.5毫米;厚度:7.4毫米;重量:162克(5.73盎司) [5]  。iPhone 12设计采用了离子玻璃,以及7000系列铝金属外壳。"}
{
    
    "index":{
    
    }}
  {
    
    "title":"iphone13","price":6000,"created_at":"2021-09-15","description":"iPhone 13屏幕采用6.1英寸OLED屏幕;高度约146.7毫米,宽度约71.5毫米,厚度约7.65毫米,重量约173克。"}
{
    
    "index":{
    
    }}
  {
    
    "title":"iphone13 pro","price":8999,"created_at":"2021-09-15","description":"iPhone 13Pro搭载A15 Bionic芯片,拥有四种配色,支持5G。有128G、256G、512G、1T可选,售价为999美元起。"}

3.2.1 すべてをクエリ [match_all]

match_all キーワード:インデックス内のすべてのドキュメントを返します。

GET /products/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  }
}

3.2.2 キーワードクエリ(用語)

term キーワード: キーワードを使用したクエリに使用されます

GET /products/_search
{
    
    
 "query": {
    
    
   "term": {
    
    
     "price": {
    
    
       "value": 4999
     }
   }
 }
}

3.2.3 範囲クエリ[範囲]

range キーワード: 指定された範囲内のドキュメントをクエリすることを指定するために使用されます。

GET /products/_search
{
    
    
  "query": {
    
    
    "range": {
    
    
      "price": {
    
    
        "gte": 5000,
        "lte": 9999
      }
    }
  }
}

3.2.4 プレフィックスクエリ[プレフィックス]

prefix キーワード: 指定された接頭辞を持つキーワードを含む関連ドキュメントを取得するために使用されます。

GET /products/_search
{
    
    
  "query": {
    
    
    "prefix": {
    
    
      "title": {
    
    
        "value": "iph"
      }
    }
  }
}

3.2.5 ワイルドカードクエリ [ワイルドカード]

ワイルドカード キーワード: ワイルドカード クエリ
? 任意の 1 文字の一致に使用 * 複数の任意の文字の一致に使用

GET /products/_search
{
    
    
  "query": {
    
    
    "wildcard": {
    
    
      "title": {
    
    
        "value": "iphone1?"
      }
    }
  }
}

3.2.6 マルチ ID クエリ [ids]

ids キーワード: 値は配列型であり、一連の ID に従って複数の対応するドキュメントを取得するために使用されます。

GET /products/_search
{
    
    
  "query": {
    
    
    "ids": {
    
    
      "values": ["pAJg84YBl2A7w00GciqN","pQJg84YBl2A7w00GciqN"]
    }
  }
}

3.2.7 ファジークエリ [ファジー]

fuzzy キーワード: 指定されたキーワードを含むドキュメントのあいまいクエリに使用されます

曖昧さ - 公式 Web サイトのアドレス
注:fuzzy 模糊查询 最大模糊错误 必须在0-2之间

  • 検索キーワードの長さは 2 で、曖昧さは許可されません
  • 検索キーワードの長さは 3 ~ 5 で、1 つのあいまいなキーワードを許可します。
  • 検索キーワードの長さが 5 を超えており、最大 2 つのブラーが許可されています
GET /products/_search
{
    
    
  "query": {
    
    
    "fuzzy": {
    
    
      "description": "phone"
    }
  }
}

3.2.8 ブールクエリ [bool]

bool キーワード: 複数の条件を組み合わせて複雑なクエリを実現するために使用されます
1 、must: 同時に確立された && と同等2、 should: ||
同等

GET /products/_search
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "should": [
        {
    
    
          "term": {
    
    
            "title": {
    
    
              "value": "iphone12"
            }
          }
        },
        {
    
    
          "term": {
    
    
            "price": {
    
    
              "value": 8999
            }
          }
        }
      ]
    }
  }
}

3.2.9 複数フィールドクエリ [multi_match]

注: クエリ条件が単語分割された後、フィールドがクエリされます。フィールドが単語分割されていない場合、クエリ条件は全体としてクエリされます。

GET /products/_search
{
    
    
  "query": {
    
    
    "multi_match": {
    
    
      "query": "iphone13 OLED屏幕",
      "fields": ["title","description"]
    }
  }
}

3.2.10 デフォルトのフィールド単語分割クエリ [query_string]

GET /products/_search
{
    
    
  "query": {
    
    
    "query_string": {
    
    
      "default_field": "description",
      "query": "大屏幕银色边"
    }
  }
}

3.2.11 ハイライトクエリ [ハイライト]

ハイライト キーワード: 修飾されたドキュメント内のキーワードをハイライトできます。
1.カスタム ハイライト HTML タグ:
---- ハイライトで使用されますpre_tagspost_tags
2.複数フィールドのハイライト
-require_field_match複数フィールドのハイライトを有効にするために使用します。

GET /products/_search
{
    
    
  "query": {
    
    
    "term": {
    
    
      "description": {
    
    
        "value": "iphone"
      }
    }
  },
  "highlight": {
    
    
    "require_field_match": "false",
    "post_tags": ["</span>"], 
    "pre_tags": ["<span style='color:red'>"],
    "fields": {
    
    
      "*":{
    
    }
    }
  }
}

3.2.12 指定された数値[サイズ]を返す

size キーワード: クエリ結果で返される項目の指定数を指定します。デフォルトの戻り値は 10 です

GET /products/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "size": 5
}

3.2.13 ページング クエリ [フォーム]

from キーワード: 戻りの開始位置を指定するために使用され、ページング効果を達成するために size キーワードと組み合わせて使用​​されます。

GET /products/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "size": 5,
  "from": 0
}

3.2.14 フィールドのソート指定[sort]

GET /products/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "sort": [
    {
    
    
      "price": {
    
    
        "order": "desc"
      }
    }
  ]
}

3.2.15 指定されたフィールド [_source] を返す

_source キーワード: 配列であり、配列内のどのフィールドを表示するかを指定するために使用されます。

GET /products/_search
{
    
    
  "query": {
    
    
    "match_all": {
    
    }
  },
  "_source": ["title","description"]
}

3.3 インデックスの原則

3.3.1 転置インデックス

倒排索引(Inverted Index)逆インデックスとも呼ばれます。逆インデックスがある場合は、順インデックスも必要です。平たく言えば、正向索引是通过key找value,反向索引则是通过value找key。ES底层在检索时底层使用的就是倒排索引。

3.3.2 インデックスモデル

既存のインデックスとマッピングは次のとおりです。

{
    
    
  "products" : {
    
    
    "mappings" : {
    
    
      "properties" : {
    
    
        "description" : {
    
    
          "type" : "text"
        },
        "price" : {
    
    
          "type" : "float"
        },
        "title" : {
    
    
          "type" : "keyword"
        }
      }
    }
  }
}

まず次のデータを入力します。タイトル、価格、説明などの 3 つのフィールドがあります。

_id タイトル 価格 説明
1 ブルームーン洗濯洗剤 19.9 ブルームーン洗濯洗剤高効率
2 iphone13 19.9 素敵な電話
3 小たぬきパリパリヌードル 1.5 アライグマおいしい

ES では、テキスト タイプの単語分割を除き、他のタイプには単語分割がないため、次のようにさまざまなフィールドに基づいてインデックスを作成します。

  • タイトルフィールド:

    学期 _id (ドキュメントID)
    ブルームーン洗濯洗剤 1
    iphone13 2
    小たぬきパリパリヌードル 3
  • 価格フィールド

    学期 _id (ドキュメントID)
    19.9 [1,2]
    1.5 3
  • 説明フィールド

    学期 _id 学期 _id 学期 _id
    1 いいえ 2 小さい 3
    1 間違い 2 ラクーン 3
    明るい 1 2 クマ 3
    洗う 1 2 良い 3
    1 マシーン 2 食べる 3
    液体 1
    とても [1:1:9、2:1:6、3:1:6]
    高い 1
    効果 1

注意: Elasticsearch分别为每个字段都建立了一个倒排索引。因此查询时查询字段的term,就能知道文档ID,就能快速找到文档。

3.3.3 トークナイザー

内蔵トークナイザー

  • standardアナライザー - デフォルトのトークナイザー。英語は単語と小文字で分割されます。
  • simpleアナライザー - 単語によるセグメント化 (シンボルはフィルター処理されます)、小文字の処理
  • stopアナライザー - 小文字処理、ストップワード フィルタリング (the、a、is)
  • whitespaceアナライザー - スペースに従って分割し、小文字に変換しません
  • keywordアナライザー - 単語を分割せず、入力を出力として直接処理します。
POST /_analyze
{
    
    
  "analyzer": "standard",
  "text": "this is a , good Man 中华人民共和国"
}

3.3.3.2 インデックスの作成と単語の分割の設定

PUT /索引名
{
    
    
  "settings": {
    
    },
  "mappings": {
    
    
    "properties": {
    
    
      "title":{
    
    
        "type": "text",
        "analyzer": "standard" //显式指定分词器
      }
    }
  }
}

3.3.3.3 中国語トークナイザー

ES では、 smartCNIKなど、多くの中国語トークナイザがサポートされており、これをお勧めしますIK分词器

IKトークナイザーをインストールする

オープンソース アドレス-Ik tokenizer-github
オープンソース アドレス-Ik tokenizer-gitee

  • 注意IK トークナイザーのバージョンでは、同じバージョンの ES をインストールする必要があります
  • 注意ES インストール プラグインを実行する Docker コンテナのディレクトリは/usr/share/elasticsearch/pluginsです
  • 注意ダウンロードが Maven 構造の場合、Maven をパッケージ化して、ターゲットの jar ファイルの下のプラグインに移動する必要があります。
  • ここに画像の説明を挿入
  • 注意倉庫の下に階段がございますのでご利用ください
  • 正しいディレクトリここに画像の説明を挿入
# 1. 下载对应版本
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.14.0/elasticsearch-analysis-ik-7.14.0.zip

# 2. 解压 #先使用yum install -y unzip
unzip elasticsearch-analysis-ik-7.14.0.zip

# 3. 移动解压文件到es的挂载目录下
 如:~/es/plugins
# 4. 重启es生效

# 5. 本地安装ik配置目录为  
- es安装目录中/plugins/analysis-ik/config/IKAnalyzer.cfg.xml

IK使用

IK には 2 つの粒度分割があります。

  • ik_smart: 最も粗い分割を実行します

ここに画像の説明を挿入

  • ik_max_word: テキストを最も細かい粒度に分割します

ここに画像の説明を挿入

拡張ワード、ストップワードの設定

IK はカスタマイズをサポートしており扩展词典停用词典

  • 扩展词典一部の単語はキーワードではありませんが、ES が検索用のキーワードとして使用することを期待しており、これらの単語は拡張辞書に追加できます。
  • 停用词典一部の単語はキーワードですが、ビジネス シナリオでの検索にこれらのキーワードを使用したくない場合は、これらの単語を無効な辞書に入れることができます。

拡張辞書を定義し、辞書を無効にすると、 IK トークナイザーのconfigディレクトリ内のIKAnalyzer.cfg.xmlこのファイルが変更される可能性があります。

1. 修改vim IKAnalyzer.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
    <comment>IK Analyzer 扩展配置</comment>
    <!--用户可以在这里配置自己的扩展字典 -->
    <entry key="ext_dict">ext_dict.dic</entry>
     <!--用户可以在这里配置自己的扩展停止词字典-->
    <entry key="ext_stopwords">ext_stopword.dic</entry>
</properties>

2. 在ik分词器目录下config目录中创建ext_dict.dic文件   编码一定要为UTF-8才能生效
vim ext_dict.dic 加入扩展词即可

3. 在ik分词器目录下config目录中创建ext_stopword.dic文件 
vim ext_stopword.dic 加入停用词即可

4.重启es生效

3.4 フィルタクエリ「フィルタクエリ」

ES でのクエリ操作は、查询(query)と の2 つのタイプに分類されます过滤(filter)query查询デフォルトでは、返されたドキュメントごとにスコアが計算され、スコア順に並べ替えられます。代わりに、过滤(filter)一致するドキュメントをフィルターで除外するだけで、スコアは計算せず、ドキュメントをキャッシュできます。パフォーマンスの観点から見ると、フィルタリングはクエリよりも高速です。过滤适合在大范围筛选数据,而查询则适合精确匹配数据。一般应用时, 应先使用过滤操作过滤数据, 然后使用查询匹配数据。

使用

GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [
        {
    
    "match_all": {
    
    }} //查询条件
      ],
      "filter": {
    
    ....} //过滤条件
  }
}
  • 注意:
    • フィルタとクエリを実行する場合は、まずフィルタを実行してからクエリを実行します
    • Elasticsearch は、頻繁に使用されるフィルターを自動的にキャッシュしてパフォーマンスを高速化します。

タイプ

一般的なフィルタリング タイプには、 term 、 term 、 ranage、exists、ids およびその他のフィルタが含まれます。

term 、 term フィルター (条件)

# 使用term过滤器
GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [{
    
    "match_all": {
    
    }}],
      "filter": {
    
    
        "term": {
    
    
          "description":"iphone"
        }  
      }
    } 
  }
}

#使用terms过滤器
GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [{
    
    "match_all": {
    
    }}],
      "filter": {
    
    
        "terms": {
    
    
          "description": [
            "13",
            "宽度"
          ]
        }  
      }
    } 
  }
}

範囲フィルター (範囲)

GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [{
    
    "match_all": {
    
    }}],
      "filter": {
    
    
        "range": {
    
    
          "price": {
    
    
            "gte": 1000,
            "lte": 6666
          }
        }  
      }
    } 
  }
}

存在するフィルター (存在する)

指定されたフィールドに null 値を持つドキュメントをフィルターし、特定のフィールドに値を持つドキュメントのみを検索します

GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [{
    
    "match_all": {
    
    }}],
      "filter": {
    
    
        "exists": {
    
    
          "field": "description"
        }  
      }
    } 
  }
}

IDフィルター

指定したフィールドを含むインデックス レコードをフィルターする

GET /products/_search 
{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": [{
    
    "match_all": {
    
    }}],
      "filter": {
    
    
        "ids": {
    
    
          "values": ["SsAW94YB8GbnoR-aVwio","TMAW94YB8GbnoR-aVwiw"]
        }  
      }
    } 
  }
}

ここに画像の説明を挿入

4.スプリングブートを統合する

4.1 依存関係の導入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

4.2 クライアントの構成

@Configuration
public class RestClientConfig extends AbstractElasticsearchConfiguration {
    
    
    @Override
    @Bean
    public RestHighLevelClient elasticsearchClient() {
    
    
        final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
                .connectedTo("172.16.91.10:9200")
                .build();
        return RestClients.create(clientConfiguration).rest();
    }
}

4.3 クライアントオブジェクト

  • Elasticsearchオペレーション
  • RestHighLevelClient お勧め
関連メモ
@Document(indexName = "es_product")//创建索引的名称
public class ESProduct {
    
    
    @Id //@Id 用在属性上  作用:将对象id字段与ES中文档的_id对应
    @Field(type = FieldType.Text)
    private String id;
    @Field(type=FieldType.Text,analyzer="ik_max_word") //type: 用来指定字段类型,analyzer:指定分词器
    private String title;
    @Field(type = FieldType.Double)
    private Double price;
    @Field(type=FieldType.Text,analyzer="ik_max_word")
    private String description;
    //格式化时间日期
    @Field( type = FieldType.Date,format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss")
    private Date createTime;
    @Field( type = FieldType.Date,format = DateFormat.custom, pattern = "yyyy-MM-dd HH:mm:ss")
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern ="yyyy-MM-dd HH:mm:ss")
    private Date updateTime;
}
統合されたクエリ
public Map<String, Object> searchProduct(QueryReq queryReq) throws IOException {
    
    
    Map<String, Object> result = new HashMap<>();
    // 指定只能在哪些文档库中查询:可以添加多个且没有限制,中间用逗号隔开 --- 默认是去所有文档库中进行查询
    SearchRequest searchRequest = new SearchRequest("es_product");
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS)); //设置超时时间
    String[] includeFields = new String[] {
    
    "id","title","price","description","createTime"};
    String[] excludeFields = new String[] {
    
    ""};

    //多字段高亮
    HighlightBuilder highlightBuilder = new HighlightBuilder();
    HighlightBuilder.Field highlightTitle = new HighlightBuilder.Field("title");
    highlightBuilder.field(highlightTitle);
    HighlightBuilder.Field highlightDescription = new HighlightBuilder.Field("description");
    highlightBuilder.field(highlightDescription);
    highlightBuilder.requireFieldMatch(false).preTags("<span style='color:red;'>").postTags("</span>");

    sourceBuilder.fetchSource(includeFields, excludeFields);
    sourceBuilder
            //分页
            .from((queryReq.getPage() - 1) * queryReq.getLimit())
            .size(queryReq.getLimit())
            .sort("price", SortOrder.DESC)
            .fetchSource(includeFields, excludeFields)
            .highlighter(highlightBuilder);

    BoolQueryBuilder all = QueryBuilders.boolQuery()
            .must(QueryBuilders.matchAllQuery());

    //检索title和description
    if(!StringUtils.isEmpty(queryReq.getKeyword())){
    
    
        all.filter(QueryBuilders.multiMatchQuery(queryReq.getKeyword(), "description", "title"));
    }

    //价格
    if(queryReq.getMin_price() != null){
    
    
        all.filter(QueryBuilders.rangeQuery("price").gte(queryReq.getMin_price()));
    }

    if(queryReq.getMax_price() != null){
    
    
        all.filter(QueryBuilders.rangeQuery("price").lte(queryReq.getMax_price()));
    }

    sourceBuilder.query(all);
    searchRequest.source(sourceBuilder);
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

    //处理结果
    SearchHit[] hits = searchResponse.getHits().getHits();
    List<ESProduct> list = new ArrayList<>();
    ObjectMapper objectMapper = new ObjectMapper();
    for (SearchHit hit : hits) {
    
    
        ESProduct esProduct = objectMapper.readValue(hit.getSourceAsString(), ESProduct.class);
        Map<String, HighlightField> highlightFields = hit.getHighlightFields();
        if (highlightFields.containsKey("title")) {
    
    
            esProduct.setTitle(highlightFields.get("title").getFragments()[0].toString());
        }
        if (highlightFields.containsKey("description")) {
    
    
            esProduct.setDescription(highlightFields.get("description").getFragments()[0].toString());
        }
        list.add(esProduct);
    }
    long totalHits = searchResponse.getHits().getTotalHits().value;
    result.put("data",list);
    result.put("count",totalHits);
    result.put("code",0);
    return result;
}

集計クエリ (SQL のグループ化に似ています)

公式 Web サイトのドキュメント - 集計

アグリゲーション:英語ではAggregationで、検索機能とは別にesが提供するesデータを統計分析する機能です集約は、検索クエリに基づいて集約されたデータを提供するのに役立ちます。集計クエリはデータベースの重要な機能であり、ES は検索エンジンおよびデータベースとして強力な集計分析機能も提供します。

バケット集計(Bucket Aggregation)
バケット集計とは、文書を複数のバケット(Bucket)に分けて統計を行う集計方法です。たとえば、文書を特定のフィールドに基づいてグループ化し、各グループ内の文書数、最大値、最小値、平均値などの統計結果を返すことができます。バケット集計をネストして、より複雑な統計と分析を実現できます。

メトリック集約 (メトリック集約)
メトリック集約は、ドキュメント コレクションに対して数値計算を実行するための集約方法です。たとえば、ドキュメントのコレクション内の数値フィールドの合計、平均、最大値、最小値などを計算できます。

パイプライン集計 (Pipeline Aggregation)
パイプライン集計は、集計結果を再処理するための集計方法です。たとえば、特定のバケット集計の結果に対して並べ替え、フィルタリング、パーセンタイルの計算、移動平均の計算などの操作を実行して、集計に基づいてデータをより深く分析および理解することができます。

#求和
GET /es_product/_search
{
    
    
  "size":0,
  "aggs":{
    
    
    "aggs_name=sum_price":{
    
    
      "sum":{
    
    
        "field":"price"
      }
    }
  }
}
#最大值
GET /es_product/_search
{
    
    
  "size":0,
  "aggs":{
    
    
      "max_price":{
    
    
          "max":{
    
    
              "field":"price"
          }
      }
  }
}
#最小值(Min)
GET /es_product/_search
{
    
    
  "size":"0",
  "aggs":{
    
    
      "min_price":{
    
    
          "min":{
    
    
              "field":"price"
          }
      }
  }
}
#平均值(Avg)
GET /es_product/_search
{
    
    
  "size":"0",
  "aggs":{
    
    
      "avg_price":{
    
    
          "avg":{
    
    
              "field":"price"
          }
      }
  }
}
#去重数值(cardinality)不同价格的商品件数
GET /es_product/_search
{
    
    
  "size":0,
  "aggs":{
    
    
    "price_count":{
    
    
      "cardinality": {
    
    
        "field": "price"
      }
    }
  }
}
#多值查询-最大最小值和平均值
GET /es_product/_search
{
    
    
  "size":0,
  "aggs":{
    
    
    "max_price":{
    
    
      "max":{
    
    
        "field":"price"
      }
    },
    "min_price":{
    
    
      "min":{
    
    
        "field":"price"
      }
    },
    "avg_price":{
    
    
      "avg":{
    
    
        "field":"price"
      }
    }
  }
}
# 返回多个聚合值(Status) --直接显示多种聚合结果,总记录数,最大值,最小值,平均值,汇总
GET /es_product/_search
{
    
    
  "size":0,
  "aggs":{
    
    
    "price_stats":{
    
    
      "stats":{
    
    
        "field":"price"
      }
    }
  }
}

ここに画像の説明を挿入

アプリケーションの統合 – 複数の集計値を返す

public Map<String, Object> aggregation() throws IOException {
    
    
    SearchRequest searchRequest = new SearchRequest("es_product");
    SearchSourceBuilder aggregationBuilder = new SearchSourceBuilder();
    aggregationBuilder.aggregation(AggregationBuilders.stats("priceStatsAgg").field("price"));
    searchRequest.source(aggregationBuilder);
    SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
    Aggregations aggregations = searchResponse.getAggregations();
    ParsedStats statsAgg = aggregations.get("priceStatsAgg");
    Map<String, Object> result = new HashMap<>();
    List<Map<String, Object>> data = new ArrayList<>();
    Map<String, Object> dataMap = new HashMap<>();
    //获取聚合值
    dataMap.put("min",statsAgg.getMin());
    dataMap.put("max",statsAgg.getMax());
    dataMap.put("avg",statsAgg.getAvg());
    dataMap.put("sum",statsAgg.getSum());
    dataMap.put("count",statsAgg.getCount());
    data.add(dataMap);
    result.put("data",data);
    result.put("code",0);
    return result;
}

集計とクエリは同じレベルにあり、クエリ メソッドで集計できますが、対応する型を取得するには、取得された集計結果を取得する必要があります。そうしないと、変換エラーが発生します。
ここに画像の説明を挿入

ウェアハウスのアドレス: https://gitcode.net/chendi/springboot_elasticsearch_demo


要約する

Elasticsearchは、全文検索、データ分析、データマイニングなどのさまざまな機能を実現できるLuceneベースの分散検索エンジンです。

  1. インデックス「インデックス」は、mysql のデータベースの概念に似ています。
  2. マッピング「mapping」はmysqlのフィールドタイプに対応するフィールド名に似ています。
  3. ドキュメント「ドキュメント」は、mysql のレコードの行に似ています。
  4. 単語分割の概念 - 単語分割の種類
  5. 高度な検索
  6. フィルタークエリ
  7. Client オブジェクト - RestHighLevelClient によって一般的に使用されます
  8. 集計クエリは、mysql の groupby やその他の関数に似ています。

おすすめ

転載: blog.csdn.net/weixin_45549188/article/details/129739821