如何从MongoDB同步仅更新数据至Solr Core?无需全量导入
解决Solr与MongoDB增量同步的几种可行方案
当然有更高效的增量同步方案,不用每次全量导入折腾!我之前做Solr+MongoDB的搜索系统时也遇到过这个痛点,下面几个方案都是实际落地过的,你可以根据自己的技术栈和场景选择:
方案1:MongoDB Change Streams + 自定义同步服务
MongoDB 3.6及以上版本支持Change Streams,它能实时捕获集合的插入、更新、删除等变更操作。你可以写个轻量服务(Python/Java/Node.js都行)监听这个流,然后把变更同步到Solr:
- 前置条件:MongoDB必须部署为副本集(Change Streams依赖副本集的oplog)
- 核心步骤:
- 编写监听代码,订阅目标集合的Change Stream,过滤出
insert、update、delete事件 - 针对不同事件调用Solr API:
- 插入/更新:调用Solr的
/update接口提交文档(注意更新时要带上唯一ID) - 删除:调用
/update接口发送删除指令,比如stream.body=<delete><id>文档ID</id></delete>
- 插入/更新:调用Solr的
- 断点续传处理:把最后成功处理的事件ID存在配置集合或本地文件里,服务重启后从该位置继续监听,避免重复同步或遗漏
- 编写监听代码,订阅目标集合的Change Stream,过滤出
方案2:Solr DataImportHandler(DIH)增量导入
Solr自带的DIH支持增量同步,只要你的MongoDB集合有标记更新的字段,配置起来很方便:
- 前置准备:给MongoDB集合添加时间戳字段(比如
last_updated)或自增版本号,确保数据更新时这个字段会被同步修改(比如更新操作里设置last_updated: new Date()) - 配置示例(修改
data-config.xml):<dataConfig> <dataSource type="MongoDataSource" database="your_db_name" collection="your_collection" /> <document> <entity name="your_entity" query="{}" <!-- 全量导入时的查询 --> deltaQuery="{'last_updated': {'$gt': '${dataimporter.last_index_time}'}}" <!-- 增量查询:找出上次导入后更新的数据 --> deltaImportQuery="{'_id': '${dataimporter.delta._id}'}" <!-- 获取增量数据的完整内容 --> deletedPkQuery="{'_id': {'$in': [已删除的ID列表]}}" <!-- 可选:捕获删除的文档ID,同步到Solr删除 --> transformer="MongoMapperTransformer"> <field column="_id" name="id" /> <!-- 映射Solr的唯一ID --> <field column="title" name="title" /> <!-- 其他字段映射 --> <field column="last_updated" name="last_updated" /> </entity> </document> </dataConfig> - 触发增量导入:
- 手动调用:
http://your_solr_host:8983/solr/your_core/dataimport?command=delta-import - 自动定时:用Cron任务或定时脚本定期执行上述请求,实现准实时同步
- 手动调用:
方案3:第三方CDC工具(比如Debezium)
如果不想自己写代码或配置DIH,可以用成熟的CDC(Change Data Capture)工具:
- Debezium:专门捕获数据库变更的工具,完美支持MongoDB。它会把MongoDB的变更事件发送到Kafka,你可以写个Kafka消费端把事件同步到Solr;也可以通过配置让Debezium直接输出到Solr,减少中间环节
- 优势:无需修改业务代码,能实时捕获所有变更,包括删除操作,适合对同步实时性要求高的场景
关键注意事项
- 数据一致性:不管用哪种方案,都要处理网络中断、服务重启等异常情况,做好重试机制,避免数据丢失或重复
- 删除同步:DIH默认不会处理删除操作,需要额外配置
deletedPkQuery;Change Streams和Debezium能直接捕获删除事件,同步更省心 - 版本兼容性:确保Solr、MongoDB以及第三方工具的版本互相兼容,比如Debezium对MongoDB的版本有要求
内容的提问来源于stack exchange,提问作者rahulchauhan
相关产品推荐
相关产品推荐

