Spring data Elasticsearch动态更改indexName

Cha*_*ang 4 spring elasticsearch spring-data spring-data-elasticsearch

我正在尝试使用 spring data elastisearch 保存一些数据。我需要为不同的客户端创建相同的索引。前任。如果我有索引my-index,我需要为客户端A和B创建my-index-A、my-index-B。但是注释@Document仅适用于静态indexName或非线程安全的spEL。

我的问题是,如果我手动创建索引和搜索(ElasticsearchTemplate.createIndex()、NativeSearchQueryBuilder().withIndices()),并删除实体类上的这一行。

@Document(indexName = "my-index-A")
Run Code Online (Sandbox Code Playgroud)

该实体仍然可以收到它的值吗?换句话说,注释

@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;
Run Code Online (Sandbox Code Playgroud)

还有效吗?

ibe*_*xit 5

长话短说

\n\n

如果删除 Spring-Data-Elasticseach 将\xc2\xb4t 不再工作@Document如果您从类中

\n\n

解释:

\n\n

如果您@Document从类中删除,则在读取或写入时(确定索引名称、类型和 id 时),多个 Elasticsearch 操作将失败,如下所示ElasticsearchTemplate.getPersistentEntityFor(Class clazz)严重依赖于此注释。

\n\n

解决方案

\n\n

我已经成功地使用带有虚拟注释的一个带注释的类来成功地读取/写入不同的索引@Document(indexName = "dummy", createIndex = false),并使用elasticsearchTemplate 为所有读/写操作显式设置索引名称。

\n\n

证明

\n\n

写作

\n\n
    ElasticEntity foo = new ElasticEntity();\n    foo.setAid("foo-a-id");\n    foo.setEntityId("foo-entity-id");\n    foo.setUserName("foo-user-name");\n    foo.setUserId("foo-user-id");\n\n    IndexQuery fooIdxQuery = new IndexQueryBuilder()\n            .withIndexName("idx-foo")\n            .withObject(foo)\n            .build();\n\n    String fooId = template.index(fooIdxQuery);\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
    ElasticEntity bar = new ElasticEntity();\n    bar.setAid("bar-a-id");\n    bar.setEntityId("bar-entity-id");\n    bar.setUserName("bar-user-name");\n    bar.setUserId("bar-user-id");\n\n    IndexQuery barIdxQuery = new IndexQueryBuilder()\n            .withIndexName("idx-bar")\n            .withObject(bar)\n            .build();\n\n    String barId = template.index(barIdxQuery);\n
Run Code Online (Sandbox Code Playgroud)\n\n

应该将对象存储在不同的索引中。

\n\n

双重检查curl http://localhost:9200/idx-*/_search?pretty给出:

\n\n
{\n  "took" : 3,\n  "timed_out" : false,\n  "_shards" : {\n    "total" : 10,\n    "successful" : 10,\n    "skipped" : 0,\n    "failed" : 0\n  },\n  "hits" : {\n    "total" : 2,\n    "max_score" : 1.0,\n    "hits" : [\n      {\n        "_index" : "idx-bar",\n        "_type" : "elasticentity",\n        "_id" : "bar-a-id",\n        "_score" : 1.0,\n        "_source" : {\n          "aid" : "bar-a-id",\n          "userId" : "bar-user-id",\n          "entityId" : "bar-entity-id",\n          "userName" : "bar-user-name"\n        }\n      },\n      {\n        "_index" : "idx-foo",\n        "_type" : "elasticentity",\n        "_id" : "foo-a-id",\n        "_score" : 1.0,\n        "_source" : {\n          "aid" : "foo-a-id",\n          "userId" : "foo-user-id",\n          "entityId" : "foo-entity-id",\n          "userName" : "foo-user-name"\n        }\n      }\n    ]\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如您所见,响应中的索引名称和 _id 是正确的。

\n\n

使用以下代码也可以进行读取(您\xc2\xb4ll需要根据您的需要更改查询并将索引设置为当前客户端)

\n\n
SearchQuery searchQuery = new NativeSearchQueryBuilder()\n              .withQuery(matchAllQuery())\n              .withIndices("idx-foo", "idx-bar")\n              .build();\n\nList<ElasticEntity> elasticEntities = template.queryForList(searchQuery, ElasticEntity.class);\nlogger.trace(elasticEntities.toString());\n
Run Code Online (Sandbox Code Playgroud)\n\n

映射也可以作为logger结果中会产生完全填充的类:

\n\n
[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)]\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这有帮助!

\n