我正在尝试使用spring数据elastisearch保存一些数据。我需要为不同的客户端创建相同的索引。例如如果我有索引my-index,则需要为客户端A和B创建my-index-A,my-index-B。但是批注@Document仅适用于静态indexName或不线程安全的spEL。
我的问题是,如果我创建索引并手动搜索(ElasticsearchTemplate.createIndex(),NativeSearchQueryBuilder()。withIndices())并删除实体类上的这一行。
@Document(indexName = "my-index-A")
实体仍然可以接收其值吗?换句话说,注释
@Id
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
private String aid;
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
private String userId;
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
private String entityId;
@Field(index = FieldIndex.not_analyzed, type = FieldType.String)
private String userName;
仍然有效吗?
答案 0 :(得分:0)
TL; DR
如果从班级中删除@Document
批注,则Spring-Data-Elasticseach将不再起作用。
说明:
如果您从类中删除@Document
,则由于ElasticsearchTemplate.getPersistentEntityFor(Class clazz)
严重依赖此注释,因此在读写时(确定索引名称,类型和ID时),一些Elasticsearch操作将失败。
解决方案
我已经成功地使用带有虚拟注释@Document(indexName = "dummy", createIndex = false)
的带注释的类成功地读取/写入了不同的索引,并使用elasticsearchTemplate显式设置了所有读取/写入操作的索引名称。
证明
用
书写 ElasticEntity foo = new ElasticEntity();
foo.setAid("foo-a-id");
foo.setEntityId("foo-entity-id");
foo.setUserName("foo-user-name");
foo.setUserId("foo-user-id");
IndexQuery fooIdxQuery = new IndexQueryBuilder()
.withIndexName("idx-foo")
.withObject(foo)
.build();
String fooId = template.index(fooIdxQuery);
和
ElasticEntity bar = new ElasticEntity();
bar.setAid("bar-a-id");
bar.setEntityId("bar-entity-id");
bar.setUserName("bar-user-name");
bar.setUserId("bar-user-id");
IndexQuery barIdxQuery = new IndexQueryBuilder()
.withIndexName("idx-bar")
.withObject(bar)
.build();
String barId = template.index(barIdxQuery);
应将对象存储在不同的网络索引中。
使用curl http://localhost:9200/idx-*/_search?pretty
进行两次检查会得出:
{
"took" : 3,
"timed_out" : false,
"_shards" : {
"total" : 10,
"successful" : 10,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "idx-bar",
"_type" : "elasticentity",
"_id" : "bar-a-id",
"_score" : 1.0,
"_source" : {
"aid" : "bar-a-id",
"userId" : "bar-user-id",
"entityId" : "bar-entity-id",
"userName" : "bar-user-name"
}
},
{
"_index" : "idx-foo",
"_type" : "elasticentity",
"_id" : "foo-a-id",
"_score" : 1.0,
"_source" : {
"aid" : "foo-a-id",
"userId" : "foo-user-id",
"entityId" : "foo-entity-id",
"userName" : "foo-user-name"
}
}
]
}
}
如您所见,响应中的索引名称和_id是正确的。
阅读也可以使用以下代码(您需要根据需要更改查询并将索引设置为当前客户端)
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withIndices("idx-foo", "idx-bar")
.build();
List<ElasticEntity> elasticEntities = template.queryForList(searchQuery, ElasticEntity.class);
logger.trace(elasticEntities.toString());
映射也起作用,因为logger
在结果中产生完全填充的类:
[ElasticEntity(aid=bar-a-id, userId=bar-user-id, entityId=bar-entity-id, userName=bar-user-name), ElasticEntity(aid=foo-a-id, userId=foo-user-id, entityId=foo-entity-id, userName=foo-user-name)]
希望这对您有帮助!