最近在使用MongoDB的时候,遇到了使用多个关键词进行模糊查询的场景。竹风使用的是mongoengine库。

查了各种资料,最后总结出比较好用的方法。先上代码,后面进行详细说明。如下:

 #!/usr/bin/env python
#coding:utf-8 import re
import mongoengine
from mongoengine import * mongoengine.register_connection('default', 'test', host='127.0.0.1') class TestData(Document):
name = StringField()
content = StringField() TestData.objects.get_or_create(name='天地玄黄',defaults={'content':'abc123'})
TestData.objects.get_or_create(name='宇宙洪荒',defaults={'content':'ABC123'})
TestData.objects.get_or_create(name='天天向上',defaults={'content':'Abc123'}) def print_arr(obj):
print obj.name,obj.content def fuzzy_query_by_contains():
print "\n###使用mongoengine的contains进行查询"
print "#contains区分大小写:"
test_data_list = TestData.objects(content__contains='abc123')
map(print_arr,test_data_list) print "#icontains不区分大小写:"
test_data_list = TestData.objects(content__icontains='abc123')
map(print_arr,test_data_list) def fuzzy_query_by_Q():
print "\n###使用Q来进行查询"
test_data_list = TestData.objects(
Q(name__icontains=u'天地') | Q(name__icontains=u'宇宙'))
map(print_arr,test_data_list) def fuzzy_query_by_pymongo():
print "\n###使用raw queries,New in version 0.4"
print "#单个查询条件"
search = {
'__raw__':{
'content':{'$regex':'A\S+\d+'},
},
}
test_data_list = TestData.objects(**search)
map(print_arr,test_data_list) print "#多个查询条件"
search = {
'__raw__':{
'name':{'$in':[re.compile(u'天天'),re.compile(u'宇宙')]},
},
}
test_data_list = TestData.objects(**search)
map(print_arr,test_data_list) if __name__ == '__main__':
fuzzy_query_by_contains()
fuzzy_query_by_Q()
fuzzy_query_by_pymongo()

先讨论一下fuzzy_query_by_contains方法,这里用的是mongoengine提供的contains操作。值得注意的是,contains区分大小写,而icontains不区分大小写。这种方式在针对一个关键词进行模糊查询的时候特别方便。

然后是fuzzy_query_by_Q方法,这里结合了contains和Q来进行组合查询。当使用Q()来进行组合查询时,必须使用位运算符(|和&),而不能使用or,and来进行逻辑运算。这种方式比较合适确定关键词数目的情况。如果关键词的数目是不定的,这种方式就略显纠结了。

竹风在动态关键词模糊查询的问题也是纠结良久,差点就要对每个关键词分别查询,然后取交集凑结果了。后来在文档中发现,mongoengine有__raw__这个参数,可以执行PyMongo的查询(version 0.4提供的新功能)。于是几经试验,fuzzy_query_by_pymongo方法就出炉了。
    PyMongo支持正则表达式,提供了两种方法,一种是使用$regex,另一种是使用re.compile()。
    在例子中,对单个关键词进行模糊查询,对应的代码为:{'$regex':'A\S+\d+'}
    接着就是对多个关键词进行查询,对应的代码为:{'$in':[re.compile(u'天天'),re.compile(u'宇宙')]}

对代码进行一些修改,以便接受多个关键词,代码如下:

 def fuzzy_query_by_pymongo():
print "#多个查询条件"
keyword = u'天天 宇宙'
search = {'__raw__' : {'name':{'$in':map(re.compile,keyword.split())}}}
test_data_list = TestData.objects(**search)
map(print_arr,test_data_list)

顺带一提,例子中创建数据是用的get_or_create,会返回一个元组,第一个元素是创建or查询的对象,第二个元素是是否创建成功。文档中的推荐用法如下:

 >>> a, created = User.objects.get_or_create(name='User A', defaults={'age': })
>>> b, created = User.objects.get_or_create(name='User A', defaults={'age': })
>>> a.name == b.name and a.age == b.age
True

最后是例子运行的结果,返回的结果顺序可能略有不同,不必在意。

 $ python mongodb_test.py

 ###使用mongoengine的contains进行查询
#contains区分大小写:
天地玄黄 abc123
#icontains不区分大小写:
天地玄黄 abc123
宇宙洪荒 ABC123
天天向上 Abc123 ###使用Q来进行查询
天地玄黄 abc123
宇宙洪荒 ABC123 ###使用raw queries,New in version 0.4
#单个查询条件
宇宙洪荒 ABC123
天天向上 Abc123
#多个查询条件
宇宙洪荒 ABC123
天天向上 Abc123

Python札记 -- MongoDB模糊查询的更多相关文章

  1. Python 代码实现模糊查询

    Python 代码实现模糊查询 1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的文件名,并提供一个推荐列 ...

  2. 转】Nodejs对MongoDB模糊查询

    原博文出自于: http://blog.fens.me/category/%E6%95%B0%E6%8D%AE%E5%BA%93/page/4/ 感谢! Posted: Jul 1, 2013 Tag ...

  3. 10 行 Python 代码实现模糊查询/智能提示

    10 行 Python 代码实现模糊查询/智能提示   1.导语: 模糊匹配可以算是现代编辑器(如 Eclipse 等各种 IDE)的一个必备特性了,它所做的就是根据用户输入的部分内容,猜测用户想要的 ...

  4. MongoDB 模糊查询,及性能测试

    var mongodb = new MongoClient("mongodb://127.0.0.1:27017");//MongoServer.Create();//创建链接 v ...

  5. MongoDB模糊查询

    模糊查询简介MongoDB查询条件可以使用正则表达式,从而实现模糊查询的功能.模糊查询可以使用$regex操作符或直接使用正则表达式对象. MySQL  MongoDB select * from s ...

  6. MongoDB 模糊查询like

    1.LIKE模糊查询userName包含A字母的数据(%A%)-- SQL:SELECT * FROM UserInfo WHERE userName LIKE "%A%" -- ...

  7. MongoDB模糊查询,以及MongoDB模糊查询时带有括号的情况

    模糊查询 记录如下: { "_id" : ObjectId("5c3d486d24aa9a000526367b"), "name" : &q ...

  8. MongoDB模糊查询 工具

    {"Exception":{$regex:"定时发送邮件"}}    //模糊查询条件 {"DateTime":-1}         // ...

  9. Python——数据库like模糊查询

    在Python中%是一个格式化字符,所以如果需要使用%则需要写成%%.将在Python中执行的sql语句改为:sql = "SELECT * FROM table_test WHERE va ...

随机推荐

  1. Python之Scrapy爬虫框架安装及简单使用

    题记:早已听闻python爬虫框架的大名.近些天学习了下其中的Scrapy爬虫框架,将自己理解的跟大家分享.有表述不当之处,望大神们斧正. 一.初窥Scrapy Scrapy是一个为了爬取网站数据,提 ...

  2. 如何系统地自学一门Python 语言(转)

    转自:http://www.phpxs.com/post/4521 零基础情况下,学一门语言充实下自己,Python,简洁.优美.容易使用,是一个很好的选择.那么如何系统地自学Python呢? 有的人 ...

  3. io流(详询请加qq:2085920154)

    import java.io.File; import java.io.FileInputStream; import java.io.IOException; public class ioTest ...

  4. android Handler机制详解

      简单运行图:    名词解析: Message(消息):定义了一个包含描述以及随意的数据对象可以被发送到Hanlder的消息,获得消息的最好方法是Message.obtain或者Handler.o ...

  5. 安装odoo服务

    sysv init 服务 从 odoo 源码 debian 目录 拷贝 init 至 /etc/init.d/ 并 更名为 odoo cd /opt/odoo sudo cp /opt/odoo/de ...

  6. js阻止提交表单(post)

    在注册页面,我们经常要用到页面验证,验证到不符合要求的数据就阻止提交到服务器,如下 <script type="text/javascript"> function C ...

  7. c++ chap1 to chap 3

    #ifndef MAIN_H_INCLUDED#define MAIN_H_INCLUDED struct Course{ int id; std::string name;}; const int ...

  8. android调用系统相机并获取图片

    如果不是特别的要求,通过拍照的方式取得图片的话,我们一般调用系统的拍照来完成这项工作,而没必要再自己去实现一个拍照功能.调用系统相机很简单,只需要一个intent就可以跳转到相几界面,然后再通过onA ...

  9. spring自动装配

    spring提供了自动装配(autowiring)和自动检测(autodiscovery)用来减少XML的配置数量. 自动装配bean属性 byName——把与Bean的属性具有相同名字(或ID)的其 ...

  10. eclipse js 引用跳转

    引用 http://stackoverflow.com/questions/24505993/the-resource-is-not-on-the-build-path-of-a-javascript ...