- プロジェクトが使用されるたび、再構築されるたびにピットを踏むことになるため、建設と統合に多大な時間を費やすことを避けるために、いくつかのピットがここに記録されます。
- インストール
圧縮パッケージ elasticsearch-6.2.4 を解凍用に準備する
- config フォルダーの下にある elasticsearch.yml ファイルを構成します。お気に入りのポートと構成アカウントのパスワードを変更できます。
- 中国語ワードブレーカーをインストールする
トークナイザーのバージョンは elasticsearch と一致している必要があることに注意してください
解凍したフォルダーをESルートディレクトリ下のpluginsディレクトリに置き、ESを再起動して使用します。
リリース · medcl/elasticsearch-analysis-ik · GitHub
2、クラスターを構成する
3.1 elasticsearch-cluster フォルダーの作成
3 つの elasticsearch サービスを内部的にレプリケートします。
3.2クラスターファイルディレクトリ内の各ノードのconfig/elasticsearch.yml設定ファイルを変更する
ノード-1001 ノード
#节点 1 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
#节点名称,集群内要唯一
node.name: node-1001
node.master: true
node.data: true
#ip 地址
#必须要指定ip,若localhost则只能本机访问
network.host: localhost
#http 端口
http.port: 1001
#tcp 监听端口
transport.tcp.port: 9301
#discovery.seed_hosts: ["localhost:9301", "localhost:9302","localhost:9303"]
#discovery.zen.fd.ping_timeout: 1m
#discovery.zen.fd.ping_retries: 5
#集群内的可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1", "node-2","node-3"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"
ノード-1002 ノード
#节点 2 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
#节点名称,集群内要唯一
node.name: node-1002
node.master: true
node.data: true
#ip 地址
network.host: localhost
#http 端口
http.port: 1002
#tcp 监听端口
transport.tcp.port: 9302
discovery.seed_hosts: ["localhost:9301"]
discovery.zen.fd.ping_timeout: 1m
discovery.zen.fd.ping_retries: 5
#集群内的可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1", "node-2","node-3"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"
必要に応じて、各ノードのデータ ディレクトリの内容をすべて削除します。エラーを防ぐ
3.3クラスタの起動
実行ノードの bin/elasticsearch.bat を順にダブルクリックしてノード サーバーを起動します (スクリプトを作成して起動することもできます) 起動後、指定した名前でクラスターに自動的に参加します。
3.4 テストクラスター
1. Postman を使用してクラスターのステータスを表示する
http://127.0.0.1:1001/_cluster/health を取得します
http://127.0.0.1:1002/_cluster/health を取得します
http://127.0.0.1:1003/_cluster/healthを取得します
返されれば成功
3. 断片化
4、スプリングブートの統合
1. まず、pom.xml に Maven 依存関係を追加します。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<!--<version>2.2.6.RELEASE</version>-->
<!--这里可不具体版本,会自动按照springboot版本注入合适版本-->
</dependency>
バージョン要件は公式に固有です
Spring Data Elasticsearch - リファレンスドキュメント
2. springboot 構成ファイルを追加します
2つの方法があります
1 つ目は、ポート tcp 9300 を介して接続することです。このバージョンの springboot は elasticsearch のバージョンと互換性があります。
Spring.data.elasticsearch.repositories.enabled= true
Spring.data.elasticsearch.cluster-nodes= 127.0.0.1:9300
Spring.data.elasticsearch.cluster-name= elasticsearch
このメソッドは ElasticSearchTemplate を使用します
もう 1 つは http 経由です
Spring.elasticsearch.rest.uris= 172.0.11.121:9201
このメソッドは ElasticSearchRestTemplate を使用します
このように、springboot と elasticsearch のバージョンは公式の要件を満たしている必要があります。
プロジェクトに Redis 依存関係が含まれている場合
次にスタートアップクラスを追加します
System.setProperty("es.set.netty.runtime.available.processors","false");
es の netty を使用せず、redis を使用します。
3. データを ES に保存する必要があるエンティティ クラスは、アノテーションを追加する必要があります。
@Document(indexName = "shopping", shards = 3, replicas = 1,type="product")
//indexName相当于数据库的库名,type 相当于表名
public class Product {
//必须有 id,这里的 id 是全局唯一的标识,等同于 es 中的"_id"
@Id
private Long id;//商品唯一标识
/**
* type : 字段数据类型
* analyzer : 分词器类型
* index : 是否索引(默认:true)
* Keyword : 短语,不进行分词
*/
@Field(type = FieldType.Text, analyzer = "ik_max_word")
private String title;//商品名称
@Field(type = FieldType.Keyword)
private String category;//分类名称
@Field(type = FieldType.Double)
private Double price;//商品价格
@Field(type = FieldType.Keyword, index = false)
private String images;//图片地址
}
4.構成クラス
ElasticsearchRestTemplate は、他の Spring プロジェクトのテンプレートと同様、spring-data-elasticsearch プロジェクトのクラスです。
spring-data-elasticsearch の新しいバージョンでは、ElasticsearchRestTemplate が元の ElasticsearchTemplate を置き換えます。
その理由は、ElasticsearchTemplate は TransportClient に基づいており、TransportClient は 8.x 以降のバージョンでは削除されるためです。したがって、ElasticsearchRestTemplate を使用することをお勧めします。
ElasticsearchRestTemplate は RestHighLevelClient クライアントに基づいています。RestHighLevelClient オブジェクトを作成するには、構成クラスをカスタマイズし、AbstractElasticsearchConfiguration を継承し、elasticsearchClient() 抽象メソッドを実装する必要があります。
- カスタム構成クラスが必要です
AbstractElasticsearchConfiguration を継承し、elasticsearchClient() 抽象メソッドを実装して RestHighLevelClient オブジェクトを作成します。
import lombok.Data;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
@ConfigurationProperties(prefix = "elasticsearch")
@Configuration
@Data
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration{
private String host ;
private Integer port ;
//重写父类方法
@Override
public RestHighLevelClient elasticsearchClient() {
RestClientBuilder builder = RestClient.builder(new HttpHost(host, port));
RestHighLevelClient restHighLevelClient = new
RestHighLevelClient(builder);
return restHighLevelClient;
}
}
- DAOデータアクセスオブジェクト
import com.lun.model.Product;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface ProductDao extends ElasticsearchRepository<Product, Long>{
}
- 汚い操作
import com.lun.dao.ProductDao;
import com.lun.model.Product;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESProductDaoTest {
@Autowired
private ProductDao productDao;
/**
* 新增
*/
@Test
public void save(){
Product product = new Product();
product.setId(2L);
product.setTitle("华为手机");
product.setCategory("手机");
product.setPrice(2999.0);
product.setImages("http://www.atguigu/hw.jpg");
productDao.save(product);
}
//POSTMAN, GET http://localhost:9200/product/_doc/2
//修改
@Test
public void update(){
Product product = new Product();
product.setId(2L);
product.setTitle("小米 2 手机");
product.setCategory("手机");
product.setPrice(9999.0);
product.setImages("http://www.atguigu/xm.jpg");
productDao.save(product);
}
//POSTMAN, GET http://localhost:9200/product/_doc/2
//根据 id 查询
@Test
public void findById(){
Product product = productDao.findById(2L).get();
System.out.println(product);
}
@Test
public void findAll(){
Iterable<Product> products = productDao.findAll();
for (Product product : products) {
System.out.println(product);
}
}
//删除
@Test
public void delete(){
Product product = new Product();
product.setId(2L);
productDao.delete(product);
}
//POSTMAN, GET http://localhost:9200/product/_doc/2
//批量新增
@Test
public void saveAll(){
List<Product> productList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Product product = new Product();
product.setId(Long.valueOf(i));
product.setTitle("["+i+"]小米手机");
product.setCategory("手机");
product.setPrice(1999.0 + i);
product.setImages("http://www.atguigu/xm.jpg");
productList.add(product);
}
productDao.saveAll(productList);
}
//分页查询
@Test
public void findByPageable(){
//设置排序(排序方式,正序还是倒序,排序的 id)
Sort sort = Sort.by(Sort.Direction.DESC,"id");
int currentPage=0;//当前页,第一页从 0 开始, 1 表示第二页
int pageSize = 5;//每页显示多少条
//设置查询分页
PageRequest pageRequest = PageRequest.of(currentPage, pageSize,sort);
//分页查询
Page<Product> productPage = productDao.findAll(pageRequest);
for (Product Product : productPage.getContent()) {
System.out.println(Product);
}
}
}
- 複雑なクエリ検索操作
import com.lun.dao.ProductDao;
import com.lun.model.Product;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringDataESSearchTest {
@Autowired
private ProductDao productDao;
/**
* term 查询
* search(termQueryBuilder) 调用搜索方法,参数查询构建器对象
*/
@Test
public void termQuery(){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");
Iterable<Product> products = productDao.search(termQueryBuilder);
for (Product product : products) {
System.out.println(product);
}
}
/**
* term 查询加分页
*/
@Test
public void termQueryByPage(){
int currentPage= 0 ;
int pageSize = 5;
//设置查询分页
PageRequest pageRequest = PageRequest.of(currentPage, pageSize);
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("title", "小米");
Iterable<Product> products =
productDao.search(termQueryBuilder,pageRequest);
for (Product product : products) {
System.out.println(product);
}
}
}
パッケージAPI