【问题标题】:Spring Data Elasticsearch: Multiple Index with same DocumentSpring Data Elasticsearch:具有相同文档的多个索引
【发布时间】:2015-04-12 12:33:48
【问题描述】:

我正在使用 spring-data-elasticsearch,一开始一切正常。

@Document( type = "products", indexName = "empty" )
public class Product
{
...
}

public interface ProductRepository extends ElasticsearchRepository<Product, String>
{
...
}

在我的模型中我可以搜索产品。

@Autowired
private ProductRepository repository;
...
repository.findByIdentifier( "xxx" ).getCategory() );

所以,我的问题是 - 我在不同的索引中有相同的 Elasticsearch 类型,我想对所有查询使用相同的文档。我可以通过池处理更多连接 - 但我不知道如何实现这一点。

我想拥有类似的东西:

ProductRepository customerRepo = ElasticsearchPool.getRepoByCustomer("abc", ProductRepository.class);
repository.findByIdentifier( "xxx" ).getCategory();

是否可以在运行时创建具有不同索引的存储库?

非常感谢 马塞尔

【问题讨论】:

    标签: java elasticsearch spring-boot spring-data spring-data-elasticsearch


    【解决方案1】:

    是的。春天是可能的。但是你应该使用ElasticsearchTemplate 而不是Repository

    例如。我有两种产品。它们存储在不同的索引中。

    @Document(indexName = "product-a", type = "product")
    public class ProductA {
    
        @Id
        private String id;
    
        private String name;
    
        private int value;
    
        //Getters and setters
    }
    
    @Document(indexName = "product-b", type = "product")
    public class ProductB {
    
        @Id
        private String id;
    
        private String name;
    
        //Getters and setters
    
    }
    

    假设如果它们具有相同的类型,那么它们具有相同的字段。但这不是必需的。两种产品可以有完全不同的领域。

    我有两个仓库:

    public interface ProductARepository extends ElasticsearchRepository<ProductA, String> {
    }
    
    
    public interface ProductBRepository
        extends ElasticsearchRepository<ProductB, String> {
    
    
    }
    

    也没有必要。仅用于测试。 ProductA 存储在“product-a”索引中,ProductB 存储在“product-b”索引中。

    如何查询两个(十、十)同类型的索引?

    只需像这样构建自定义存储库

    @Repository
    public class CustomProductRepositoryImpl {
    
        @Autowired
        private ElasticsearchTemplate elasticsearchTemplate;
    
        public List<ProductA> findProductByName(String name) {
            MatchQueryBuilder queryBuilder = QueryBuilders.matchPhrasePrefixQuery("name", name);
    
            //You can query as many indices as you want
            IndicesQueryBuilder builder = QueryBuilders.indicesQuery(queryBuilder, "product-a", "product-b");
    
            SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
    
            return elasticsearchTemplate.query(searchQuery, response -> {
                SearchHits hits = response.getHits();
                List<ProductA> result = new ArrayList<>();
                Arrays.stream(hits.getHits()).forEach(h -> {
                    Map<String, Object> source = h.getSource();
                    //get only id just for test
                    ProductA productA = new ProductA()
                            .setId(String.valueOf(source.getOrDefault("id", null)));
                    result.add(productA);
                });
                return result;
            });
        }
    
    }
    

    您可以搜索任意数量的索引,并且可以将此行为透明地注入ProductARepository adding custom behavior to single repositories

    第二种解决方案是使用indices aliases,但您也必须创建自定义模型或自定义存储库。

    【讨论】:

      【解决方案2】:

      如果需要,我们可以使用the withIndices method来切换索引:

      NativeSearchQueryBuilder nativeSearchQueryBuilder = nativeSearchQueryBuilderConfig.getNativeSearchQueryBuilder();
      // Assign the index explicitly.
      nativeSearchQueryBuilder.withIndices("product-a");
      // Then add query as usual.
      nativeSearchQueryBuilder.withQuery(allQueries)
      

      entity中的@Document注解只会明确映射关系,要查询具体的索引,还是需要使用上面的方法。

      @Document(indexName="product-a", type="_doc")
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-15
        • 2021-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多