MongoDB 数据自动同步到 ElasticSearch

本文详细介绍了如何将MongoDB与ElasticSearch集成,解决中文全文检索问题,包括部署流程、遇到的问题及解决方案。

我们产品中需要全文检索的功能,后端数据存储主要使用了 MySQL + MongoDB,而其中需要检索的内容是在 MongoDB 中的。

MongoDB 本身是自带文本索引功能的,但是,不支持中文。术业有专攻,MongoDB 是数据存储应用,那么全文检索就使用专业的全文搜索引擎吧。

预选的几个选手有:Solr、ElasticSearch、Xapian、Sphinx、XunSearch。由于我们的数据量比较大,觉得现在单机已经有些力不从心了,MongoDB 也开始计划做分片,那么全文搜索如果自带分布式技能那就最合适不过了。经过一系列的考量,最后,我们就决定用 ElasticSearch 了。

现在后端程序是直接将数据写到 MongoDB 中,我不想修改程序代码,不想在增删改 MongoDB 中数据的同时去增删改 ElasticSearch 中的数据。希望 MongoDB 中数据发送变化时自动同步到 ElasticSearch 中,这样就可以最快地用上 ElasticSearch 了。

刚开始我找到的方案是利用 ElasticSearch 的 River 来同步数据,并在 GitHub 上到了 MongoDB River 插件:elasticsearch-river-mongodb。但是,随后我又在 ElasticSearch 官网上看了这篇博客:《Deprecating Rivers》,官方已经在 1.5 以后的版本弃用 River,为了用户的迁移,会一直保留到 2.0 版本。

于是,我得另寻方案了。然后我又在网上找到了另外一个方案:mongo-connector。这个是 MongoDB 官方的开发人员用 Python 写的一个工具,目前支持将 MongoDB 的数据同步到 Solr、ElasticSearch、MongoDB 中,并且支持用户自己扩展。看到 README 中的免责声明,我有点觉得这是玩票性质的工具,但是还是抱着试试看的心态决定试试看了。

下面是部署过程:

  1. MongoDB 必须开启复制集,如果已经开启请忽略这一步:
    配置复制集的名称:mongod --replSet myDevReplSet
    在 mongo shell 中初始化复制集:rs.initiate()

  2. 安装 ElasticSearch,如果已经安装请忽略这一步。

  3. 安装 mongo-connector:
    先安装 pip:

    yum install python-setuptools && easy_install pip

    通过 pip 安装 mongo-connector:

    pip install mongo-connector
  4. 运行 mongo-connector:

    mongo-connector -m 127.0.0.1:27017 -t 127.0.0.1:9200 -d elastic_doc_manager

OK,现在,在 MongoDB 中增删改数据,都能立刻同步到 ElasticSearch 中了。在试用过程中,mongo-connector 退出过两次,其中一次断开太久没有发觉,害我不得不重新同步。还是有点不靠谱的感觉,可能还得专门写个守护程序,让 mongo-connector 一直能在后台好好干活。

拓展阅读:

### MongoDB数据同步Elasticsearch的方法 #### 工具选择 可以使用多种工具来完成MongoDBElasticsearch之间的数据同步。其中一种常用的方式是通过Python脚本实现,这种方式具有较高的灵活性和可控性[^1]。 以下是基于Python的一个简单示例代码,用于从MongoDB读取数据并将其批量导入至Elasticsearch: ```python from pymongo import MongoClient from elasticsearch import Elasticsearch, helpers import datetime # 连接MongoDB client_mongo = MongoClient('mongodb://localhost:27017/') db_mongo = client_mongo['your_database'] collection_mongo = db_mongo['your_collection'] # 连接Elasticsearch es_client = Elasticsearch(['http://localhost:9200/']) # 定义数据转换函数 def transform_doc(doc): doc['_id'] = str(doc.pop('_id')) # 将ObjectId转为字符串 return { "_index": "your_index", "_type": "_doc", "_source": doc } # 批量导出数据 cursor = collection_mongo.find({}) bulk_data = (transform_doc(doc) for doc in cursor) # 使用helpers.bulk方法执行批量插入 response = helpers.bulk(es_client, bulk_data) print(response) ``` 此代码片段展示了如何通过`pymongo`库连接MongoDB,并通过`elasticsearch-py`库将数据推送到Elasticsearch中。为了提高效率,采用了批量操作方式[^1]。 #### 自动化解决方案 另一种自动化方案是利用Elasticsearch曾经提供的River插件,不过该功能已被废弃。因此推荐采用Logstash作为替代品[^2]。Logstash能够实时捕获MongoDB的变化日志并通过其输入插件传输给Elasticsearch。 配置文件如下所示: ```yaml input { mongodb { uri => 'mongodb://localhost:27017/' placeholder_db_dir => '/path/to/placeholder/db' placeholder_db_name => 'logstash_sqlite.db' batch_size => 500 } } output { elasticsearch { hosts => ["http://localhost:9200"] index => "your_index" } } ``` 上述配置定义了一个Logstash管道,它定期查询MongoDB并将新记录发送到指定的Elasticsearch索引下[^2]。 #### 字段映射注意事项 当涉及复杂文档结构时(如嵌套JSON),需特别注意字段类型的匹配问题。例如,在某些情况下,MongoDB中的子文档应被扁平化后再存储于Elasticsearch之中[^3]。可以通过自定义逻辑调整源数据格式以满足目标系统的预期需求。 另外值得注意的是时间戳处理方面可能存在差异,建议统一采用ISO8601标准表示法以便跨平台兼容[^4]。 #### 平台级选项 对于更复杂的场景或者更大规模的企业应用环境来说,考虑部署专业的ETL工具可能是更好的选择。像Talend Open Studio、Hevo Data以及提到过的RestCloud等都提供了图形化的界面简化整个流程设置过程[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值