spring-data-elasticsearch

v2026.09.24

Spring Data Elasticsearch for full-text search and analytics. Covers ElasticsearchOperations, repositories, aggregations, and index management. USE WHEN: user mentions "spring data elasticsearch", "ElasticsearchRepository", "ElasticsearchOperations", "@Document elasticsearch", "Spring Boot Elasticsearch" DO NOT USE FOR: raw Elasticsearch queries - use `elasticsearch` instead, ELK stack setup - use `elasticsearch` instead

GitHub
安装命令
npx skhub add claude-dev-suite/spring-data-elasticsearch
Markdown
SKILL.md

Spring Data Elasticsearch - Quick Reference

Full Reference: See advanced.md for aggregations, autocomplete/suggestions, bulk operations, index management, and Testcontainers integration.

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: spring-data-elasticsearch for comprehensive documentation.

Dependencies

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

Configuration

spring:
  elasticsearch:
    uris: http://localhost:9200
    username: ${ELASTICSEARCH_USERNAME:}
    password: ${ELASTICSEARCH_PASSWORD:}
    connection-timeout: 5s
    socket-timeout: 30s

Document Mapping

@Document(indexName = "products")
public class Product {

    @Id
    private String id;

    @Field(type = FieldType.Text, analyzer = "standard")
    private String name;

    @Field(type = FieldType.Text, analyzer = "standard")
    private String description;

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

    @Field(type = FieldType.Double)
    private BigDecimal price;

    @Field(type = FieldType.Integer)
    private Integer stock;

    @Field(type = FieldType.Boolean)
    private boolean active;

    @Field(type = FieldType.Date, format = DateFormat.date_hour_minute_second)
    private LocalDateTime createdAt;

    @Field(type = FieldType.Nested)
    private List<ProductAttribute> attributes;

    @Field(type = FieldType.Keyword)
    private List<String> tags;
}

Repository Pattern

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

    List<Product> findByCategory(String category);
    List<Product> findByNameContaining(String name);
    List<Product> findByPriceBetween(BigDecimal min, BigDecimal max);
    List<Product> findByActiveTrue();

    // Pagination
    Page<Product> findByCategory(String category, Pageable pageable);

    // Sorting
    List<Product> findByCategoryOrderByPriceAsc(String category);

    // Count / Exists / Delete
    long countByCategory(String category);
    boolean existsByName(String name);
    void deleteByCategory(String category);
}

Custom Queries

public interface ProductRepository extends ElasticsearchRepository<Product, String> {

    @Query("""
        {
          "multi_match": {
            "query": "?0",
            "fields": ["name^3", "description", "tags"],
            "type": "best_fields",
            "fuzziness": "AUTO"
          }
        }
        """)
    Page<Product> fullTextSearch(String query, Pageable pageable);
}

ElasticsearchOperations

@Service
@RequiredArgsConstructor
public class ProductSearchService {

    private final ElasticsearchOperations elasticsearchOperations;

    public SearchHits<Product> search(ProductSearchCriteria criteria) {
        BoolQuery.Builder boolQuery = new BoolQuery.Builder();

        if (StringUtils.hasText(criteria.getQuery())) {
            boolQuery.must(MultiMatchQuery.of(m -> m
                .query(criteria.getQuery())
                .fields("name^3", "description", "tags")
                .fuzziness("AUTO")
            )._toQuery());
        }

        if (StringUtils.hasText(criteria.getCategory())) {
            boolQuery.filter(TermQuery.of(t -> t
                .field("category")
                .value(criteria.getCategory())
            )._toQuery());
        }

        NativeQuery query = NativeQuery.builder()
            .withQuery(boolQuery.build()._toQuery())
            .withPageable(PageRequest.of(criteria.getPage(), criteria.getSize()))
            .build();

        return elasticsearchOperations.search(query, Product.class);
    }
}

Best Practices

DoDon't
Use appropriate field typesMap everything as text
Define proper analyzersUse default for all
Use filters for exact matchesUse match for keywords
Paginate large result setsFetch all documents at once

When NOT to Use This Skill

  • Raw Elasticsearch API - Use elasticsearch skill for REST API
  • ELK stack setup - Use elasticsearch skill
  • Primary database - Elasticsearch is for search, not ACID transactions

Anti-Patterns

Anti-PatternProblemSolution
Refresh after each writePerformance degradationUse refresh_interval, batch
Deep pagination with from/sizeMemory issuesUse search_after
Mapping all as textPoor search, high diskUse appropriate field types
No index lifecycleDisk exhaustionConfigure ILM policies
Fetching all fieldsWasted bandwidthUse source filtering

Quick Troubleshooting

ProblemDiagnosticFix
Connection failedCheck Elasticsearch runningStart ES, check URI, SSL
Index not foundCheck index nameCreate index, check @Document
Mapping conflictCheck field typesReindex with correct mapping
Search returns nothingCheck analyzerTest with _analyze API
Version conflictCheck @VersionHandle OptimisticLockingFailureException

Production Checklist

  • Cluster configured (3+ nodes)
  • Shards and replicas set
  • Index lifecycle management
  • Proper mapping defined
  • Analyzers configured
  • Bulk operations for indexing
  • Monitoring enabled
  • Security enabled

Reference Documentation

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

skills/databases/spring-data-elasticsearch

默认分支

main

最新提交

9496306

Tree SHA

fe4e2f1