Spring Data Elasticsearch的@Field注释不起作用 [英] Spring Data Elasticsearch's @Field annotation not working

查看:4289
本文介绍了Spring Data Elasticsearch的@Field注释不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在pom.xml中有一个带有Spring Data Elasticsearch插件的Spring Boot应用程序。我创建了一个我想要索引的文档类:

  @Document(indexName =操作,type =operation)
public class OperationDocument {

@Id
private Long id;

@Field(
type = FieldType.String,
index = FieldIndex.analyzed,
searchAnalyzer =standard,
indexAnalyzer =standard ,
store = true

private String operationName;

@Field(
type = FieldType.Date,
index = FieldIndex.not_analyzed,
store = true,
format = DateFormat.custom,pattern =dd.MM.yyyy hh:mm

私人日期dateUp;

@Field(
type = FieldType.String,
index = FieldIndex.not_analyzed,
store = false

private String someTransientData ;

@Field(type = FieldType.Nested)
private List< Sector>行业;

// Getter和setter

我还创建了一个这个类的存储库:

  public interface OperationDocumentRepository 
extends ElasticsearchRepository< OperationDocument,Long>我做了一个测试,使用存储库索引三个示例对象。这很长,所以我会发布它只是需要。事实是,在ES服务器中创建的映射忽略由@Field注释设置的配置:

 mappings:{
operation:{
properties:{
operationName:{
type:string
},
dateUp {
type:long
},
someTransientData:{
type:string
},
:{
properties:{
id:{
type:long
},
sectorName:{
type:string
}
}
}
}
}
}
/ pre>

没有关于分析器的信息,someTransientData被存储和编入索引,dateUp键入Long而不是Date。



直接从服务器请求的示例文档:

  {
_index:operations,
_type:operation,
_id:AUyUk2cY3nXeOFxdOlQW,
_version:1,
_score:1,
_source:{
id:null,
operationName:第二操作名称,
dateUp:1428421827091,
someTransientData:不要索引或存储,
sectors:[
{
id:2,
sectorName:保健
},
{
id:3,
sectorName:建设
}
]
}
}

我还注意到,当我第二次运行应用程序时,在启动时我得到此错误仅在索引已存在时打印:


错误19452 --- [main] .dersAbstractElasticsearchRepository:加载弹性搜索节点失败:org.el asticsearch.index.mapper.MergeMappingException:合并失败{{mapper [someTransientData]具有不同的索引值,mapper [someTransientData]具有不同的标记值,mapper [someTransientData]具有不同的index_analyzer,对象映射[sector]不能更改从非嵌套到嵌套,mapper [operationName]具有不同的存储值,mapper [operationName]具有不同的index_analyzer,mapper [dateUp]的不同类型,current_type [long],merged_type [date]]}


这是Spring Data Elastic Search的错误,还是我做错了?



我试过弹簧启动和弹簧数据弹性搜索的最后一个快照提供的稳定版本。我还尝试了插件提供的嵌入式Elasticsearch服务器和当前版本的外部服务器。我总是得到相同的结果。

解决方案

我可以最终复制并解决问题。事实是,我使用ElasticTemplate来索引和搜索文档而不是存储库,因为我的业务逻辑变得更复杂(使用聚合等)。



之后,我删除了未使用的OperationDocumentRespository。似乎在启动时将类型映射发布到ES服务器需要存储库。我认为@Document类应该足够了,但不是这样。



所以我们有两个选择:




  • 保留OperationDocumentRepository

  • 将此行添加到应用程序启动:

      elasticsearchTemplate.putMapping(OperationDocument.class); 



I have a Spring Boot application with Spring Data Elasticsearch plugin in the pom.xml. I created a document class which i'd like to index:

@Document(indexName = "operations", type = "operation")
public class OperationDocument {

@Id
private Long id;

@Field(
    type = FieldType.String, 
    index = FieldIndex.analyzed, 
    searchAnalyzer = "standard", 
    indexAnalyzer = "standard",
    store = true
)
private String operationName;

@Field(
    type = FieldType.Date, 
    index = FieldIndex.not_analyzed, 
    store = true, 
    format = DateFormat.custom, pattern = "dd.MM.yyyy hh:mm"
)
private Date dateUp;

@Field(
    type = FieldType.String, 
    index = FieldIndex.not_analyzed, 
    store = false
) 
private String someTransientData;

@Field(type = FieldType.Nested)
private List<Sector> sectors;

//Getter and setters

I also created a repository for this class:

 public interface OperationDocumentRepository 
      extends ElasticsearchRepository<OperationDocument, Long> {
 }

I made a test that indexes three sample objects using the repository. It's pretty long so I'll post it only is needed. The fact is that the mapping created in the ES server ignores configuration set by @Field annotations:

"mappings": {
  "operation": {
    "properties": {
      "operationName": {
        "type": "string"
      },
      "dateUp": {
        "type": "long"
      },
      "someTransientData": {
        "type": "string"
      },
      "sectors": {
        "properties": {
          "id": {
            "type": "long"
          },
          "sectorName": {
            "type": "string"
          }
        }
      }
    }
  }
}

There is no info about analyzers, "someTransientData" is stored and indexed, and dateUp is typed as Long instead of Date.

A sample document requested directly from the server:

 {
   "_index": "operations",
   "_type": "operation",
   "_id": "AUyUk2cY3nXeOFxdOlQW",
   "_version": 1,
   "_score": 1,
   "_source": {
     "id": null,
     "operationName": "Second Operation Name",
     "dateUp": 1428421827091,
     "someTransientData": "Do not index or store",
     "sectors": [
       {
         "id": 2,
         "sectorName": "Health Care"
       },
       {
         "id": 3,
         "sectorName": "Construction"
       }
     ]
   }
 }

I also noted that when I run the application for the second time, at startup time I get this error, only printed when the index already exists:

ERROR 19452 --- [main] .d.e.r.s.AbstractElasticsearchRepository : failed to load elasticsearch nodes : org.elasticsearch.index.mapper.MergeMappingException: Merge failed with failures {[mapper [someTransientData] has different index values, mapper [someTransientData] has different tokenize values, mapper [someTransientData] has different index_analyzer, object mapping [sectors] can't be changed from non-nested to nested, mapper [operationName] has different store values, mapper [operationName] has different index_analyzer, mapper [dateUp] of different type, current_type [long], merged_type [date]]}

It's this a bug of Spring Data Elastic Search or I'm doing something wrong?

I tried the stable version provided by spring boot and last snapshot of spring-data-elasticsearch. I also tried the embedded Elasticsearch server provided by the plugin and an external one of the current version. I got always the same results.

解决方案

I could finally replicate and solve the problem. The fact is that I was using ElasticTemplate for indexing and searching docs instead of repositories, because my business logic got a more complicated (use of aggregations, etc.).

After that, I removed the unused OperationDocumentRespository. It seems that the repository is needed for the type mapping being posted to ES server on startup. I thought having the @Document class should be enough, but it isn't.

So we have two options here:

  • Keep the OperationDocumentRepository
  • Add this line to the app startup:

    elasticsearchTemplate.putMapping(OperationDocument.class);
    

这篇关于Spring Data Elasticsearch的@Field注释不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆