使用Mongo Connector和Elasticsearch实现模糊匹配

【编者按】本篇博文作者Luke Lovett是MongoDB公司的Java工程师,他展示了Mongo Connector经过2年发展后的蜕变——完成连接器两端的同步更新。期间,Luke还展示如何通过Elasticsearch实现模糊匹配。

以下为译文:

介绍

假设你正在运行MongoDB。太好了,现在已经可以为基于数据库的所有查询进行精确匹配了。现在,设想你正要在你的应用中建立一个文本搜索功能,它必须去除拼写错误这个噪音,最终可能会得到一个相近的结果。为此,这个令人生畏的任务,你需要在Lucene、Elasticsearch和Solr里选择一个。但是现在你面临这样一个问题——这些搜索工具将如何查询存储于MongoDB中的文档?以及你如何保持搜索引擎内容是最新的?

Mongo Connector填补了MongoDB和一些最好搜索工具(例如:Elasticsearch和Solr)之间的空白。这不仅是可以支撑从MongoDB副本集或这些系统分片集群中导出数据,而且可以保持这些系统之间的一致性:如果你在MongoDB中插入、更新和删除文件,那么这些改变会很快的通过Mongo Connector在另一端体现。你甚至可以使用Mongo Connector将操作以流的方式传送给其他关联副本集,从而模拟出一个“multi-master”集群。

Mongo Connector在2012年8月发布时,那个时候它的功能简单并缺少容错性。我从2013年11月开始使用Mongo连接器,期间得到了MongoDB Python团队的帮助,我非常兴奋地说它的功能和稳定性已经取得了很大进步。这篇文章将介绍这些新功能,以及如何使用Mongo Connector将MongoDB操作同步到Elasticsearch(一个开源的搜索引擎)中。在这篇文章的结尾,我们还展示如何对流入Elasticsearch中的数据实现文本查询的模糊匹配。

获取数据集

这篇文章,我们会来到一个流行的链接聚合网站Reddit。我们最近添加了一个由MongoDB提供支持的数据类型安全码,可以很好地处理外部数据库驱动器。这使得那些并没有得到充分控制的副本文档得以保证其安全性。使用下面这个脚本来传输Reddit新发布的post,使用流的方式将新生成的Reddit post传输到MongoDB中。

./reddit2mongo --mongo-host localhost --mongo-port 27017

由于post是经过处理的,你应该能看到标题的前20个字。这个过程会模仿你开发应用时的操作,将数据写入MongoDB。

启动Mongo Connector

下一步,我们将启动Mongo Connector。为了下载和安装Mongo Connector,你可以使用pip:

pip install mongo-connector

为了示例的正常进行,我们假设你已经安装好了Elasticsearch,且运行于端口为9200的本地机器。你可以使用下面的命令从 MongoDB 复制到Elasticsearch。

mongo-connector -m localhost:27017 -t localhost:9200 -d mongo_connector/doc_managers/elastic_doc_manager.py

当然,如果只想在post标题和内容中进行文本搜索,我们可以使用Elasticsearch的字段选项来限制字段。通过这个方法,我们能最小化所复制的数据量:

mongo-connector -m localhost:27017 -t localhost:9200 --fields title,text -d mongo_connector/doc_managers/elastic_doc_manager.py

就像你看到reddit2mongo将Reddit post以STDOUT输出,你同样可以看到从Mongo Connector输出的日志——所有文档都在同时发送给了ES。

弹性的搜索

现在,我们准备使用Elasticsearch在我们的数据集上实现模糊匹配查询,因为它来自于MongoDB。由于我们直接从Reddit的网站输出内容,因此根本无法预测从数据集中获得的结果。以“kitten”的搜索为例,以下为实现代码:

curl -XPOST ‘http://localhost:9200/reddit.posts/_search’ -d’{ "query": { "match": { "title": { "query": "kitten", "fuzziness": 2, "prefix_length": 1 } } }}’

由于我们正在进行一个模糊搜索,我们甚至可以搜索一个并不存在的词,例如kiten。由于大多数人根本不注重他们的拼写,它可以直接实现搜索用户随意输入的文本,至此,你可以想象这个功能是多么地强大。以下为实现代码:

curl -XPOST ‘http://localhost:9200/reddit.posts/_search’ -d’{ "query": { "match": { "title": { "query": "kiten", "fuzziness": 2, "prefix_length": 1 } } }}’

模糊参数决定了下一次查询字段匹配的最大“edit distance”, prefix_length参数则需求结果必须匹配查询的第一个字母。这篇 文章详细说明了这个功能的实现途径,输出了和正确拼写同样的结果。

不仅是插入

尽管我们只演示了如何利用从 MongoDB 到Elasticsearch的连续文件流,但是Mongo Connector不仅仅是一个输入/输出工具。当你更新或删除MongoDB中的文件时,那些操作也会被记录在其他的系统中,保持与当下的主节点同步。如果主节点在做故障转移并产生一个回滚,Mongo Connector能删除操作并采取正确的做法来维持一致性。

总结

这个事情的真正意义在于我们在MongoDB和Elasticsearch里可以同时操作。若没有一个类似Mongo Connector的工具,我们不得不使用一个类似mongoexport工具去定期地从MongoDB转储数据至JSON,然后再上传这些数据至一个闲置的Elasticsearch中,导致我们空闲时无法提前删除文件。这大概是一件很麻烦的事,同时失去了Elasticsearch的近实时查询能力。

尽管Mongo Connector自第一次发布后有了长足的改进,但它仍然是一个实验性的产品,且没有MongoDB的官方支持。然而,我会一直致力于回答各方问题、总结功能请求,并在Github Mongo Connector页面上提交Bug报告,也会检查Github百科页关于Mongo Connector的所有文档。

原文链接: How to Perform Fuzzy-Matching with Mongo Connector and ElasticSearch(翻译/红叶   责编/仲浩)

免费订阅“CSDN云计算(左)和CSDN大数据(右)”微信公众号,实时掌握第一手云中消息,了解最新的大数据进展!

CSDN发布虚拟化、Docker、OpenStack、CloudStack、数据中心等相关云计算资讯,     分享Hadoop、Spark、NoSQL/NewSQL、HBase、Impala、内存计算、流计算、机器学习和智能算法等相关大数据观点,提供云计算和大数据技术、平台、实践和产业信息等服务。

时间: 2024-11-02 04:13:45

使用Mongo Connector和Elasticsearch实现模糊匹配的相关文章

pymongo安装与模糊匹配查询

安装和更新 跟大多数py包安装一样,可以源码安装,也可以使用pip或者easy_install来安装 安装 pip install pymongo 升级 pip install --upgrade pymongo 其他安装方法请参照文档pymongo安装 记录mongo模糊匹配查询的实现方法: 在mongo中: {'filed':/value/} 使用pymongo,有以下两种方式: import re {'xxx':re.compile('xxx')} {'xxx':{'$regex':'xx

动态sql-mybatis like 模糊匹配的格式是什么样的

问题描述 mybatis like 模糊匹配的格式是什么样的 第一种 <if test="deviceName != null and deviceName != ''" > AND DEVICE_NAME LIKE '%${deviceName}%' </if> 第二种 AND DEVICE_NAME LIKE #{deviceName} 第一种之前试过是可以模糊匹配的,后来又不好用了,什么情况 还有说法是直接写like mybatis会自动加上%% 求正解

C/C++中的字符串模糊匹配

需求: 准入授权配置文件有时候分了好几个维度进行配置,例如 company|product|sys这种格式的配置: 1.配置 "sina|weibo|pusher" 表示 sina公司weibo产品pusher系统能够准入,而"sina|weibo|sign"不允许准入 2.配置 "sina|*|pusher" 表示sina公司所有产品的pusher系统都能够准入 3.配置 "*|*|pusher" 表示所有公司的所有产品的p

Oracle 11g r2数据泵新特性简介(三)数据泵对表模糊匹配导出的改进

Oracle的11gr2版本中,并没有对数据泵做出多大的改动,主要是增加了对原始版本参数的支持,并且去掉了一些小的限制. 这一篇介绍数据泵对表模糊匹配导出的改进. Oracle的数据泵支持表名的模糊匹配方式导出,比如: bash-3.00$ expdp yangtk/yangtk directory=d_output dumpfile=t_test.dp tables=t% Export: Release11.1.0.6.0 - 64bit Production on星期二, 08 9月, 20

findbugs class路径如何实现模糊匹配

问题描述 findbugs class路径如何实现模糊匹配 大家好,目前我有这么一个问题,在maven主项目下面有很多子项目,子项目分别为biz,web,timer.biz下面有target/classes还有target/biz-1.0.0-SNAPSHOT/lib/*.jar.目前我用ant配置findbugs的时候,class如果指定maven主项目的目录,会考虑lib下面的jar包.我想过滤lib下面的jar包不检查,可以写多个class,比如这样: <class location=&quo

javascript-js如何将两个值模糊匹配 像sql的like进行判断

问题描述 js如何将两个值模糊匹配 像sql的like进行判断 var str1 ; var str2; if(//这进行str1和str2的判断){ return true: }else{ return false } 解决方案 function like(str1,str2){ var result = str2.indexOf(str1);//其实就是类似contain()方法,找到str2里面是否包含有str1,不存在返回-1 if(result>0){ return true; }el

模糊匹配-Linux C++ 使用fnmatch函数匹配文件名

问题描述 Linux C++ 使用fnmatch函数匹配文件名 看了fnmatch的相关介绍 FNM_PATHNAME 如果设置了这个标志,仅在字符串中匹配斜杠以斜线(/)中,而不能由星号(*)或者一个问号(?)元字符,也由括号表达式([])包含斜杠. FNM_PERIOD 如果设置了这个标志 ,pattern 中的前导句点来匹配字符串中有精确的期限.如果被看作是领先的是字符的字符串,或如果有 fnm_pathname 是紧跟在斜杠和期限. 没看明白啊!! 我想实现一下这个功能 不知道怎么用那几

关键字的模糊匹配,数据量很大,在C#中有没有高效一点的办法,不用数据库,谢谢

问题描述 关键字的模糊匹配,数据量很大,在C#中有没有高效一点的办法,不用数据库,谢谢 关键字的模糊匹配,数据量很大,在C#中有没有高效一点的办法,不用数据库,谢谢 解决方案 分词,倒排索引,然后查询.总之要想速度快,需要多花一些存储空间. 解决方案二: C# 匹配

thinkPHP实现多字段模糊匹配查询的方法_php实例

本文实例讲述了thinkPHP实现多字段模糊匹配查询的方法.分享给大家供大家参考,具体如下: 引言:有时候查询要匹配多个字段.比如查询地址,地址是由多个字段组成的.有省.市.区等等,以及详细地址.这个时候如何查询呢? 实现不同字段相同的查询条件 $User = M("User"); // 实例化User对象 $map['name|title'] = 'thinkphp'; // 把查询条件传入查询方法 $User->where($map)->select(); 用到项目中