弹簧弹性搜索存储库不会存储数据

时间:2016-03-10 17:00:29

标签: spring scala elasticsearch

我有一个非常奇怪的问题,我基本上试图使用springboot和存储库将对象存储在弹性搜索中,并且由于某些原因,我的对象永远不会被持久化。

使用scala

完成此操作

案例类:

 @Document(collection = "SPECTRUM")
      @org.springframework.data.elasticsearch.annotations.Document(indexName = "spectrum", `type` = "spectrum", shards = 1, replicas = 0, refreshInterval = "-1")
  case class Spectrum(
                   @(Field@field)(`type` = FieldType.Nested)
                   biologicalCompound: Compound,
                   @(Field@field)(`type` = FieldType.Nested)
                   chemicalCompound: Compound,
                   @(Field@field)(`type` = FieldType.Nested)
                   predictedCompound: Compound,
                   @(Indexed@field)
                   deleted: Boolean,
                   @(Id@field)
                   id: String,
                   lastUpdated: String,
                   @(Field@field)(`type` = FieldType.Nested)
                   metaData: Array[MetaData],
                   score: Score,
                   spectrum: String,
                   splash: Splash,
                   submitter: Submitter,
                   @(Field@field)(`type` = FieldType.Nested)
                   tags: Array[Tags],
                   @(Field@field)(`type` = FieldType.Nested)
                   authors: Array[Author]
                 )

}

存储库

@Repository("spectrumElasticRepository")
trait ISpectrumElasticRepositoryCustom  extends ElasticsearchRepository[Spectrum, String]  with     SpectrumElasticRepositoryCustom{    
  def findByBiologicalCompoundInchiKey(inchiKey: String) : java.util.List[Spectrum]
}

测试代码

  getRepository.deleteAll()
  assert(getRepository.count() == 0)

      s"we should be able to store our data" in {
        for (spectrum <- exampleRecords) {
          val result = getRepository.save(spectrum)
          assert(result.isInstanceOf[Spectrum])
        }

    assert(getRepository.count() == 58)

        val data:Iterable[Spectrum] = getRepository.findAll()
      }

一旦测试代码点击此行

            val data:Iterable[Spectrum] = getRepository.findAll()

导致以下异常

failed to map source [ {}] to class Spectrum
org.springframework.data.elasticsearch.ElasticsearchException: failed to map source [ {}] to class Spectrum

直接查看弹性搜索服务器

localhost:9200/spectrum/_search

看起来没有数据实际附加到任何报告的点击

  {
    "_index": "spectrum",
    "_type": "spectrum",
    "_id": "AVNhcpHjnm4IHnHomcXj",
    "_score": 1,
    "_source": {}
  },

因为来源是空的。

任何想法是什么导致了这个?

1 个答案:

答案 0 :(得分:1)

这似乎与scala有关。

确保存储在弹性搜索数据库中的每个属性都用

索引

<强> @BeanProperty

喜欢这里

  @Document(collection = "SPECTRUM")
  @org.springframework.data.elasticsearch.annotations.Document(indexName = "spectrum", `type` = "spectra", shards = 1, replicas = 0, refreshInterval = "-1")
  case class Spectrum(
                   @BeanProperty
                   @(Field@field)(`type` = FieldType.Nested)
                   biologicalCompound: Compound,
                   @BeanProperty
                   @(Field@field)(`type` = FieldType.Nested)
                   chemicalCompound: Compound,
                   @BeanProperty
                   @(Field@field)(`type` = FieldType.Nested)
                   predictedCompound: Compound,
                   @BeanProperty
                   @(Indexed@field)
                   deleted: Boolean,
                   @BeanProperty
                   @(Id@field)
                   id: String,
                   lastUpdated: String,
                   @BeanProperty
                   @(Field@field)(`type` = FieldType.Nested)
                   metaData: Array[MetaData],
                   @BeanProperty
                   score: Score,
                   @BeanProperty
                   spectrum: String,
                   @BeanProperty
                   splash: Splash,
                   @BeanProperty
                   submitter: Submitter,
                   @BeanProperty
                   @(Field@field)(`type` = FieldType.Nested)
                   tags: Array[Tags],
                   @(Field@field)(`type` = FieldType.Nested)
                   authors: Array[Author]
                     )

}

它工作正常并且持久存在这个对象。

显然这是如此丑陋,以至于它让你想知道是否有更好的替代方案,或者编写一个scala识别包装器是有意义的。

另外,您可以使用自己选择的方法覆盖utilzied对象映射器和实体impl。这可以在您的配置类中完成。

  @Autowired
  val objectMapper:ObjectMapper = null

  @Bean
  def elasticsearchTemplate: ElasticsearchOperations = {
    new ElasticsearchTemplate(client,new EntityMapperImpl(objectMapper))
  }

  @Bean
  def client: Client = {
    val client = new TransportClient()
    val address = new InetSocketTransportAddress(hostname, port)
    client.addTransportAddress(address)

    client
  }

  class EntityMapperImpl(val mapper: ObjectMapper) extends EntityMapper {

    override def mapToString(`object`: scala.Any): String =     mapper.writeValueAsString(`object`)

    override def mapToObject[T](source: String, clazz: Class[T]): T =     mapper.readValue(source, clazz)
  }

对象映射器的确切配置看起来像

val mapper = new ObjectMapper() with ScalaObjectMapper

mapper.registerModule(DefaultScalaModule)

//required, in case we are provided with a list of value
mapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
mapper.setSerializationInclusion(Include.NON_NULL);
mapper

只需要在某处注册为bean