Java Spring Boot中的Elasticsearch入門


將Java與Elasticsearch連接

開始我們的項目

 

 

 

將依賴項添加到Spring Data Elasticsearch

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

 

創建Elasticsearch客戶的bean

spring.elasticsearch.rest.uris =本地主機:9200 
spring.elasticsearch.rest.connection-timeout = 1s 
spring.elasticsearch.rest.read-timeout = 1m 
spring.elasticsearch.rest.password = 
spring.elasticsearch.rest.username =

 

第二種方法涉及創建自己的bean。您可以通過創建RestHighLevelClientbean來配置設置如果該bean存在,Spring Data將使用它作為其配置。

@Configuration
@RequiredArgsConstructor
public class ElasticsearchConfiguration extends AbstractElasticsearchConfiguration {

  private final ElasticsearchProperties elasticsearchProperties;

  @Override
  @Bean
  public RestHighLevelClient elasticsearchClient() {
    final ClientConfiguration clientConfiguration = ClientConfiguration.builder()
        .connectedTo(elasticsearchProperties.getHostAndPort())
        .withConnectTimeout(elasticsearchProperties.getConnectTimeout())
        .withSocketTimeout(elasticsearchProperties.getSocketTimeout())
        .build();

    return RestClients.create(clientConfiguration).rest();
  }
}

 

好的,在該代碼中,我們兩次調用了Elasticsearch,RestHighLevelClient,稍后我們將在本文中學習。第一個調用是刪除索引(如果已存在)。我們使用trycatch,因為如果索引不存在。然后elasticsearch將引發錯誤,使我們的應用啟動過程失敗。

第二個調用是創建索引。由於我僅運行單節點Elasticsearch,因此我將分片配置為,將1副本配置0

如果一切正常,那么在檢查Elasticsearch時應該會看到索引。要檢查它,只需轉到http://localhost:9200/_cat/indices?v,您就可以在Elasticsearch中看到索引列表:

health status index       uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   hello-world 0NgzXS5gRxmj1eFTPMCynQ   1   1          0            0       208b           208b

 

恭喜!您只需將您的應用程序連接到Elasticsearch !!

其他連接方式

高級客戶

 

<dependency> 
    <groupId> org.elasticsearch.client </ groupId> 
    <artifactId > elasticsearch -rest-high-level-client </ artifactId> 
    <version> 8.0.0 </ version> 
</ dependency>

 

低級客戶

<dependency> 
    <groupId> org.elasticsearch.client </ groupId> 
    <artifactId > elasticsearch -rest-client </ artifactId> 
    <version> 8.0.0 </ version> 
</ dependency>

 

運輸客戶

REST TRANSPORT

 

使用Spring Data Elasticsearch

創建一個實體並配置我們的索引

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Document(indexName = "product", shards = 1, replicas = 0, refreshInterval = "5s", createIndex = true)
public class Product {
    @Id
    private String id;

    @Field(type = FieldType.Text)
    private String name;

    @Field(type = FieldType.Keyword)
    private Category category;

    @Field(type = FieldType.Long)
    private double price;

    public enum Category {
        CLOTHES,
        ELECTRONICS,
        GAMES;
    }
}

 

因此,讓我解釋一下上面的代碼塊中發生了什么。首先,我不會解釋有關@Data@AllArgsConstructor@NoArgsConstructor,和@Builder他們是從注釋龍目島庫constructorgettersetterbuilder,和其他的東西。

curl-請求GET \ 
--url http:// localhost:9200 / product / _settings
結果是:
{
  "product": {
    "settings": {
      "index": {
        "routing": {
          "allocation": {
            "include": {
              "_tier_preference": "data_content"
            }
          }
        },
        "refresh_interval": "5s",
        "number_of_shards": "1",
        "provided_name": "product",
        "creation_date": "1607959499342",
        "store": {
          "type": "fs"
        },
        "number_of_replicas": "0",
        "uuid": "iuoO8lE6QyWVSoECxa0I8w",
        "version": {
          "created": "7100099"
        }
      }
    }
  }
}

 

 

一切都如我們所配置!refresh_interval設置為5s,將number_of_shards1,將number_of_replicas0
現在,讓我們檢查一下映射:

curl-請求GET \
--url http:// localhost:9200 / product / _mappings

{
  "product": {
    "mappings": {
      "properties": {
        "category": {
          "type": "keyword"
        },
        "name": {
          "type": "text"
        },
        "price": {
          "type": "long"
        }
      }
    }
  }
}

 

具有Spring Data Repository界面的基本CRUD

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

}
@Service
@RequiredArgsConstructor
public class SpringDataProductServiceImpl implements SpringDataProductService {

  private final ProductRepository productRepository;

  public Product createProduct(Product product) {
    return productRepository.save(product);
  }

  public Optional<Product> getProduct(String id) {
    return productRepository.findById(id);
  }

  public void deleteProduct(String id) {
    productRepository.deleteById(id);
  }

  public Iterable<Product> insertBulk(List<Product> products) {
    return productRepository.saveAll(products);
  }

}

Spring Data中的自定義查詢方法

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

  List<Product> findAllByName(String name);
}
public interface ProductRepository extends ElasticsearchRepository<Product, String> {

  List<Product> findAllByName(String name);

  @Query("{\"match\":{\"name\":\"?0\"}}")
  List<Product> findAllByNameUsingAnnotations(String name);
}

使用ElasticsearchRestTemplate

 

public List<Product> getProductsByName(String name) {
    Query query = new NativeSearchQueryBuilder()
        .withQuery(QueryBuilders.matchQuery("name", name))
        .build();
    SearchHits<Product> searchHits = elasticsearchRestTemplate.search(query, Product.class);

    return searchHits.get().map(SearchHit::getContent).collect(Collectors.toList());
  }

 

 
public Map<String, Long> aggregateTerm(String term) {
    Query query = new NativeSearchQueryBuilder()
        .addAggregation(new TermsAggregationBuilder(term).field(term).size(10))
        .build();

    SearchHits<Product> searchHits = elasticsearchRestTemplate.search(query, Product.class);
    Map<String, Long> result = new HashMap<>();
    searchHits.getAggregations().asList().forEach(aggregation -> {
      ((Terms) aggregation).getBuckets()
          .forEach(bucket -> result.put(bucket.getKeyAsString(), bucket.getDocCount()));
    });

    return result;
  }

Elasticsearch RestHighLevelClient

使用RestHighLevelClient進行CRUD

@Service
@RequiredArgsConstructor
@Slf4j
public class HighLevelClientProductServiceImpl implements HighLevelClientProductService {

  private final RestHighLevelClient restHighLevelClient;
  private final ObjectMapper objectMapper;

  public Product createProduct(Product product) {
    IndexRequest indexRequest = new IndexRequest("product");
    indexRequest.id(product.getId());
    indexRequest.source(product);

    try {
      IndexResponse indexResponse = restHighLevelClient.index(indexRequest, RequestOptions.DEFAULT);
      if (indexResponse.status() == RestStatus.ACCEPTED) {
        return product;
      }

      throw new RuntimeException("Wrong status: " + indexResponse.status());
    } catch (Exception e) {
      log.error("Error indexing, product: {}", product, e);
      return null;
    }
  }
 

}

索引創建

public boolean createProductIndex() {
    CreateIndexRequest createIndexRequest = new CreateIndexRequest("product");
    createIndexRequest.settings(Settings.builder()
        .put("number_of_shards", 1)
        .put("number_of_replicas", 0)
        .put("index.requests.cache.enable", false)
        .build());
    Map<String, Map<String, String>> mappings = new HashMap<>();

    mappings.put("name", Collections.singletonMap("type", "text"));
    mappings.put("category", Collections.singletonMap("type", "keyword"));
    mappings.put("price", Collections.singletonMap("type", "long"));
    createIndexRequest.mapping(Collections.singletonMap("properties", mappings));
    try {
      CreateIndexResponse createIndexResponse = restHighLevelClient.indices()
          .create(createIndexRequest, RequestOptions.DEFAULT);
      return createIndexResponse.isAcknowledged();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return false;
  }
 

結論









免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM