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;
  }
 

结论








posted @ 2021-02-09 09:27  SUPERUSR  阅读(2637)  评论(0编辑  收藏  举报