问题 Spring Data Elasticsearch的@Field注释无法正常工作


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

@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

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

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

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

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

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

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

 {
   "_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"
       }
     ]
   }
 }

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

ERROR 19452 --- [main] .dersAbstractElasticsearchRepository:无法加载elasticsearch节点:org.elasticsearch.index.mapper.MergeMappingException:合并失败但失败{[mapper [someTransientData]具有不同的索引值,mapper [someTransientData]具有不同的tokenize值,mapper [someTransientData]有不同的index_analyzer,对象映射[sector]不能从非嵌套更改为嵌套,mapper [operationName]有不同的存储值,mapper [operationName]有不同的index_analyzer,mapper [dateUp]不同type,current_type [long],merged_type [date]]}

这是Spring Data Elastic Search的一个错误,或者我做错了什么?

我尝试了spring boot和spring-data-elasticsearch的最后一个快照提供的稳定版本。我还尝试了插件提供的嵌入式Elasticsearch服务器和当前版本的外部服务器。我总是得到相同的结果。


4018
2018-04-07 16:05


起源



答案:


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

之后,我删除了未使用的OperationDocumentRespository。似乎在启动时将类型映射发布到ES服务器需要存储库。我认为拥有@Document类应该足够了,但事实并非如此。

所以我们有两个选择:

  • 保留OperationDocumentRepository
  • 将此行添加到应用启动:

    elasticsearchTemplate.putMapping(OperationDocument.class);
    

15
2018-04-24 07:56





我试图使用spring data elasticsearch示例应用程序复制问题,但根据您的配置,我得到了如上所述的预期结果。

整个代码致力于在这里投射 - > 链接

查看在加载spring上下文时生成索引并应用映射的TestCase - > 链接

这是TestCase生成的映射:

  {
  "operations" : {
    "aliases" : { },
    "mappings" : {
      "operation" : {
        "properties" : {
          "dateUp" : {
            "type" : "date",
            "store" : true,
            "format" : "dd.MM.yyyy hh:mm"
          },
          "operationName" : {
            "type" : "string",
            "store" : true,
            "analyzer" : "standard"
          },
          "sectors" : {
            "type" : "nested"
          },
          "someTransientData" : {
            "type" : "string",
            "index" : "not_analyzed"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "refresh_interval" : "1s",
        "number_of_shards" : "5",
        "store" : {
          "type" : "fs"
        },
        "creation_date" : "1428677234773",
        "number_of_replicas" : "1",
        "version" : {
          "created" : "1040499"
        },
        "uuid" : "-djzLu-IQ0CBs-M6R0-R6Q"
      }
    },
    "warmers" : { }
  }
}

你可以使用spring boot创建类似的例子 https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-data-elasticsearch

并承诺公开分享?


1
2018-04-10 15:20



我测试了你的例子并且它有效。然后我创建了一个新的Spring Boot项目,它也有效。现在我想弄清楚是什么打破了我的第一个应用程序。如果我找到它,我会更新第一篇文章。谢谢! - WinterN
我终于可以复制并解决问题了。我在另一个答案中发布了原因和解决方案。 - WinterN


答案:


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

之后,我删除了未使用的OperationDocumentRespository。似乎在启动时将类型映射发布到ES服务器需要存储库。我认为拥有@Document类应该足够了,但事实并非如此。

所以我们有两个选择:

  • 保留OperationDocumentRepository
  • 将此行添加到应用启动:

    elasticsearchTemplate.putMapping(OperationDocument.class);
    

15
2018-04-24 07:56





我试图使用spring data elasticsearch示例应用程序复制问题,但根据您的配置,我得到了如上所述的预期结果。

整个代码致力于在这里投射 - > 链接

查看在加载spring上下文时生成索引并应用映射的TestCase - > 链接

这是TestCase生成的映射:

  {
  "operations" : {
    "aliases" : { },
    "mappings" : {
      "operation" : {
        "properties" : {
          "dateUp" : {
            "type" : "date",
            "store" : true,
            "format" : "dd.MM.yyyy hh:mm"
          },
          "operationName" : {
            "type" : "string",
            "store" : true,
            "analyzer" : "standard"
          },
          "sectors" : {
            "type" : "nested"
          },
          "someTransientData" : {
            "type" : "string",
            "index" : "not_analyzed"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "refresh_interval" : "1s",
        "number_of_shards" : "5",
        "store" : {
          "type" : "fs"
        },
        "creation_date" : "1428677234773",
        "number_of_replicas" : "1",
        "version" : {
          "created" : "1040499"
        },
        "uuid" : "-djzLu-IQ0CBs-M6R0-R6Q"
      }
    },
    "warmers" : { }
  }
}

你可以使用spring boot创建类似的例子 https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-data-elasticsearch

并承诺公开分享?


1
2018-04-10 15:20



我测试了你的例子并且它有效。然后我创建了一个新的Spring Boot项目,它也有效。现在我想弄清楚是什么打破了我的第一个应用程序。如果我找到它,我会更新第一篇文章。谢谢! - WinterN
我终于可以复制并解决问题了。我在另一个答案中发布了原因和解决方案。 - WinterN