Spring data Elasticsearch меняет indexName динамически - PullRequest
0 голосов
/ 20 ноября 2018

Я пытаюсь использовать данные пружины elastisearch, чтобы сохранить некоторые данные.Мне нужно создать один и тот же индекс для другого клиента.Ex.Если у меня есть индекс my-index, мне нужно создать my-index-A, my-index-B для клиентов A и 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;

все еще работает?

1 Ответ

0 голосов
/ 21 ноября 2018

TL; DR

Spring-Data-Elasticseach больше не будет работать, если вы удалите аннотацию @Document из своего класса.

Объяснение:

Если вы удалите @Document из своего класса, при чтении или записи (при определении имени, типа и идентификатора индекса) произойдет сбой некоторых операцийasticsearch, поскольку ElasticsearchTemplate.getPersistentEntityFor(Class clazz) в значительной степени зависит от этой аннотации.

Решение

Мне удалось успешно читать / писать с разными индексами, используя один аннотированный класс с фиктивной аннотацией @Document(indexName = "dummy", createIndex = false) и явной настройкойимя индекса для всех операций чтения / записи, использующих эластичный поиск.

Доказательство

Запись с

    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)]

Надеюсь, это помогло!

...