SpringDataElasticSearch不会隐式地从注解创建Map

2eafrhcq  于 2021-06-15  发布在  ElasticSearch
关注(0)|答案(1)|浏览(411)

我正在尝试使用spring数据elasticsearch 4.0.1,并试图找出elasticsearchMap是如何以及何时由spring创建的,或者它们是否由spring创建的。
如果我有这样一个实体:

@Document(indexName = "companies")
public class CompanyEntity {

  @Id
  private final String id;

  @MultiField(
      mainField = @Field(type = Text),
      otherFields = {
          @InnerField(suffix = "raw", type = Keyword)
      }
  )
  private final String companyName;

  @PersistenceConstructor
  public CompanyEntity(String id, String companyName) {
    this.id = id;
    this.companyName = companyName;
  }

  public String getId() {
    return id;
  }

  public String getCompanyName() {
    return companyName;
  }
}

我以为spring会隐式地为这个索引创建Map,但我似乎弄错了。elasticsearch仍会为此索引创建Map。

{
    "companies": {
        "mappings": {
            "properties": {
                "_class": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "companyName": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "id": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

很明显,innerfield注解中的后缀没有使用,也没有使用ignore\u above值,因为它默认为-1,如果尝试将ignore\u above设置为-1,elasticsearch将完全删除此字段。
我能够获得上述注解的Map的唯一方法是自己显式地设置Map。

@Autowired private ElasticsearchOperations operations;

Document mapping = operations.indexOps(CompanyEntity.class).createMapping();
operations.indexOps(CompanyEntity.class).putMapping(mapping);

从而产生预期的Map:

{
    "companies": {
        "mappings": {
            "properties": {
                "_class": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                },
                "companyName": {
                    "type": "text",
                    "fields": {
                        "raw": {
                            "type": "keyword"
                        }
                    }
                },
                "id": {
                    "type": "text",
                    "fields": {
                        "keyword": {
                            "type": "keyword",
                            "ignore_above": 256
                        }
                    }
                }
            }
        }
    }
}

这很好,但我觉得有点奇怪,因为我在官方的spring数据elasticsearch文档中找不到这种方法的任何细节。而且javadocs没有任何细节。
这是将Map从spring数据安装到elasticsearch的正确方法吗?

kiz8lqtg

kiz8lqtg1#

如果您正在使用 ElasticsearchOperations 要使用,则这是创建Map的正确方法。在版本4.1中将有一个附加的方法

boolean putMapping(Class<?> clazz)

它结合了创建和编写Map的两个步骤。 ElasticsearchOperations 以及 IndexOperations -或者更好的实现——在SpringDataElasticSearch中对elasticsearch的访问级别越低——创建索引、放置Map、编写实体等,这些都是基本操作。你可以完全控制要执行的操作,但执行这些操作是你的责任。
在此基础上构建的是存储库支持。如果定义存储库接口

interface CompanyRepository extends ElasticsearchRepository<CompanyEntity, String>{}

你把它注入到你的一个类中

@Autowired CompanyRepository repository;

然后,在应用程序启动时,springdataelasticsearch将创建此接口的实现,并检查实体的 @Document 注解存在。如果没有,它将创建索引并编写Map- @Document 注解有一个参数 createIndex 默认情况下是正确的。
因此,对于自动创建,您必须使用存储库,存储库支持还使用 ElasticsearchOperations 提供从方法名派生查询、分页支持等功能。

相关问题