简体   繁体   English

Spring Data Elasticsearch:具有相同文档的多个索引

[英]Spring Data Elasticsearch: Multiple Index with same Document

I'm using spring-data-elasticsearch and for the beginning everything works fine.我正在使用 spring-data-elasticsearch,一开始一切正常。

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

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

In my model i can search for products.在我的模型中,我可以搜索产品。

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

So, my problem is - I've the same Elasticsearch type in different indices and I want to use the same document for all queries.所以,我的问题是 - 我在不同的索引中有相同的 Elasticsearch 类型,我想对所有查询使用相同的文档。 I can handle more connections via a pool - but I don't have any idea how I can implement this.我可以通过池处理更多连接 - 但我不知道如何实现这一点。

I would like to have, something like that:我想要这样的东西:

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

Is it possible to create a repository at runtime, with an different index ?是否可以在运行时使用不同的索引创建存储库?

Thanks a lot Marcel非常感谢马塞尔

Yes.是的。 It's possible with Spring.使用 Spring 是可能的。 But you should use ElasticsearchTemplate instead of Repository .但是您应该使用ElasticsearchTemplate而不是Repository

For example.例如。 I have two products.我有两个产品。 They are stored in different indices.它们存储在不同的索引中。

@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

}

Suppose if they have the same type, so they have the same fields.假设如果它们具有相同的类型,那么它们具有相同的字段。 But it's not necessary.但这不是必需的。 Two products can have totally different fields.两种产品可以有完全不同的领域。

I have two repositories:我有两个存储库:

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


public interface ProductBRepository
    extends ElasticsearchRepository<ProductB, String> {


}

It's not necessary too.也没有必要。 Only for testing.仅用于测试。 The fact that ProductA is stored in "product-a" index and ProductB is stored in "product-b" index. ProductA存储在“product-a”索引中, ProductB存储在“product-b”索引中。

How to query two(ten, dozen) indices with the same type?如何查询两个(十,打)相同类型的索引?

Just build custom repository like this只需像这样构建自定义存储库

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

}

You can search as many indices as you want and you can transparently inject this behavior into ProductARepository adding custom behavior to single repositories您可以根据需要搜索任意数量的索引,并且可以透明地将此行为注入ProductARepository 将自定义行为添加到单个存储库

Second solution is to use indices aliases , but you had to create custom model or custom repository too.第二种解决方案是使用索引 aliases ,但您也必须创建自定义模型或自定义存储库。

We can use the withIndices method to switch the index if needed:如果需要,我们可以使用withIndices方法来切换索引:

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

The @Document annotation in entity will only clarify the mapping, to query against a specific index, we still need to use above method.实体中的@Document注解只会澄清映射,要查询特定的索引,我们仍然需要使用上述方法。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM