使用 Spring data mongo 和 Spring data elasticsearch 时如何建模?

Posted

技术标签:

【中文标题】使用 Spring data mongo 和 Spring data elasticsearch 时如何建模?【英文标题】:How to modeling when use Spring data mongo and Spring data elasticearch? 【发布时间】:2014-08-19 18:31:57 【问题描述】:

我想在我的项目中使用 mongo 和 ElasticSearch,我也喜欢采用 Spring Data Mongo 和 Spring Data ElasticSearch,但是它们都有它们的 Repository 和模型规范,如何一起使用它们?

有一些选择:

    对 Mongo 和 ElasticSearch 使用相同的模型类?

    @Document//from Spring Data Mongo
    @Document// from Spring Data ElasticSearch
    public class Book
        @Id//Spring Data Commons
        private String id;
    
    

    但是 Spring Data Mongo 和 Spring Data ElasticSearch 存在一些不匹配,比如 Geo 字段类型。

    为 Mongo 和 ElasticSearch 定义不同的模型,并在创建新模型时从 Mongo 模型中复制数据状态​​并创建索引。

这里有什么建议吗?

我想在项目中使用选项 2。

    正常保存 mongo 文档。 通过 JMS/AMQP/Reactor 触发事件以将数据同步到 Elasticsearch,并为 ElasticSearch 文档中的每个字段选择索引策略。 所有搜索操作均基于 ElasticSearch。

2016 年 5 月 15 日更新

我创建了一个示例来演示这种方法。

Sample codes

我使用 Spring 内置的 ApplicationEvent 来演示这种方法。

    事件发布者端,Mongo 保存帖子并发布事件。

    @Component
    public class Publisher implements ApplicationEventPublisherAware 
    
        private static final Logger LOG = LoggerFactory.getLogger(Publisher.class);
    
        @Autowired
        PostRepository repository;
    
        private ApplicationEventPublisher publisher;
    
        public Publisher() 
        
    
    
        public void savePost(Post post) 
            Post saved = repository.save(post);
            this.publisher.publishEvent(saved);
    
            LOG.debug("saved post data in mongo@" + saved);
        
    
        @Override
        public void setApplicationEventPublisher(ApplicationEventPublisher publisher) 
            this.publisher = publisher;
        
    
    
    

    事件接收端,接收数据并将其同步到 ElasticSearch 存储中。

        @Component
    public class Receiver 
    
        private static final Logger LOG = LoggerFactory.getLogger(Receiver.class);
    
        @Autowired
        ESPostRepository repository;
    
        @EventListener
        public void onPostSaved(Post savedPost) 
            LOG.debug("=================received post data============== @\r\n"+ savedPost);
    
            ESPost doc=new ESPost();
            doc.setId("1");
            doc.setTitle(savedPost.getTitle());
            doc.setContent(savedPost.getContent());
            repository.save(doc);
        
    
    
    

在生产环境中,发布者和接收者可以通过JMA/AMQP而不是内置的ApplicationEvent放置在不同的应用程序中。

mongo 用作主存储,ElasticSearch 用作索引/搜索服务器。

【问题讨论】:

你解决了吗?这里有同样的问题... @DavidMarko 我使用了上面列表中的第二种方法,在 ElasticSearch 和 MongoDB 中使用不同的模型。一般我们只需要部分数据作为索引,这些数据将通过 AMQP 或 Reactive Stream 异步存储在 ElasticSearch 中(例如 Reactor 项目)。并且关键字查询/搜索将与Mongo以外的ElasitcSearch握手,但该行的详细信息将从Mongo获取。 @Hantsy ,如果可能的话,您能否与我们分享工作实施的示例代码 @rajadilipkolli 我更新了我的帖子,并创建了一个工作演示来解释我的想法。 @Hantsy 感谢您的更新。 【参考方案1】:

您可以只为不同的文档注释使用完全限定的域名吗?

这就是我们在这里尝试做的事情。

  @Document(collection = "SPECTRUM")
  @org.springframework.data.elasticsearch.annotations.Document(indexName = "spectrum", `type` = "spectra", shards = 1, replicas = 0, refreshInterval = "-1")
  case class Spectrum(
                  ...
  )

【讨论】:

以上是关于使用 Spring data mongo 和 Spring data elasticsearch 时如何建模?的主要内容,如果未能解决你的问题,请参考以下文章

使用 spring data mongo 插入 Mongo 文档

如何使用 mongo 搜索集合并返回子文档列表(Spring-data-mongo)

NoSuchMethodException QueryDSL 与 Spring Boot 和 Spring Data Mongo

将 mongo 查询转换为 spring-data-mongo 查询

spring-data-mongodb 在一个 Mongo 实例中连接多个数据库

spring data mongo使用小记