【问题标题】:Solr document Custom mapping depending on typeSolr 文档根据类型自定义映射
【发布时间】:2020-12-15 11:30:36
【问题描述】:

我有一个 SOLR 服务器,为 3 种类型的实体提供信息,这些实体共享一些共同的信息。出于多种原因,我决定将所有信息存储在同一个核心中。

使用 solr data spring,我试图将文档信息从 SOLR 服务器传输到 3 类实体继承模型中:

@SolrDocument(solrCoreName = "core")
open class Item {
  common fields
  type : String = "",
  open var secondaryFields: Map<String, List<String>>? = null
}

@SolrDocument(solrCoreName = "core")
class A ( 
   @Indexed("a_*")
   override var secondaryFields: Map<String, List<String>>? = null
) : Item()

@SolrDocument(solrCoreName = "core")
class B (
  @Indexed("b_*")
  override var secondaryFields: Map<String, List<String>>? = null
) : Item()
...
class C(...)

这工作得很好,直到我尝试搜索所有文档。由于具体的类依赖于对象类型,并且默认映射到Item,所以secondaryFields属性显然没有填写相应的信息,所以secondaryFields总是为null。

我想我必须在返回的 SOLR 文档和类本身之间实现自定义映射?有可能吗?

【问题讨论】:

    标签: spring kotlin solr spring-data spring-data-solr


    【解决方案1】:

    我会在这里回答自己。我不确定这是否是最有效的解决方案,但至少它对我有用。

    我在我的 SolrConfig 类中向 solrConverter 添加了一个自定义转换器:

    @Configuration
    @EnableSolrRepositories (basePackages = ["base"])
    @ComponentScan
    class SolrConfig {
    
        @Bean
        fun solrClientFactory() : SolrClientFactory {
            return SolrClientFactory { HttpSolrClient.Builder("http://localhost:8983/solr").build() }
        }
    
        @Bean
        fun customConversions(): CustomConversions? {
            return SolrCustomConversions(arrayListOf(ItemConverter, AConverter, BConverter))
        }
    
        @Bean
        fun solrConverter(customConversions: CustomConversions): SolrConverter? {
            val solrConverter = MappingSolrConverter(SimpleSolrMappingContext())
            solrConverter.setCustomConversions(customConversions)
            return solrConverter
        }
    
        @Bean
        @Throws(java.lang.Exception::class)
        fun solrTemplate(clientFactory: SolrClientFactory, solrConverter: SolrConverter) : SolrTemplate {
            return SolrTemplate(clientFactory, solrConverter)
        }
    }
    

    转换器如下:

    @ReadingConverter
    object ItemConverter : Converter<SolrDocument, Item> {
        override fun convert(source: SolrDocument): Item {
            val mappingSolrConverter = MappingSolrConverter(SimpleSolrMappingContext())
            if (source.getFieldValue("type") == companion.A_TYPE) {
                return mappingSolrConverter.read(A::class.java, source)
            }
            if (source.getFieldValue("type") == companion.B_TYPE) {
                return mappingSolrConverter.read(B::class.java, source)
            }
            return mappingSolrConverter.read(Item::class.java, source)
        }
    }
    @ReadingConverter
    object AConverter : Converter<SolrDocument, A> {
        override fun convert(source: SolrDocument): A {
            val mappingSolrConverter = MappingSolrConverter(SimpleSolrMappingContext())
            return mappingSolrConverter.read(A::class.java, source)
        }
    }
    

    等等。所以基本上我正在做的是调用默认的 MappingSolrConverter 但根据字段“类型”读取适当的子类。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-23
      • 1970-01-01
      • 2012-12-23
      • 2019-01-25
      • 2011-08-14
      • 1970-01-01
      相关资源
      最近更新 更多