最近在使用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. console.log()与alert()的区别

    1.alert() a.有阻塞作用,不点击确定,后续代码无法继续执行 b.alert只能输出string,如果alert输出的是对象,会自动调用toString()方法 eg:alert([1,2,3 ...

  2. 转:jsp页面显示中文乱码解决方案

    jsp页面显示中文乱码: jsp页面的编码方式有两个地方需要设置: <%@ page language="java" import="java.util.*&quo ...

  3. linux 下进程通讯详解

    linux 下进程通讯方法主要有以下六种: 1.管道 2.信号 3.共享内存 4.消息队列 5.信号量 6.socket

  4. (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  5. python课程第一周重点记录

  6. [ASP.NET]配置使用SQL Server保存会话状态

    会话状态是ASP.NET应用程序状态的其中一种,这种状态的特点是以用户为单位,每个会话对应一个用户,也就是说在该用户的整个访问过程,会话状态保存的数据都会持续保存于服务器的介质中,直到会话超时(即用户 ...

  7. Verilog经典输入控制/激励信号模板1

    :]i;   always @ ( posedge CLOCK or negedge RESET )  if( !RESET ) begin  i <= 'd0;  Start_Si ...

  8. rem介绍

    手机端开发,一般以320px宽为最低标题.市场上的手机,大多数是360px宽. 20px=1rem是最容易换算的,基本上可以口算,除以2并缩小十倍.1px/20=0.05rem.两位小数就可以除尽了. ...

  9. 基于Xenomai和工控机的实时测控系统的研究

    http://www.docin.com/p-1006254643-f6.html

  10. Gray Code

    Gray Code The gray code is a binary numeral system where two successive values differ in only one bi ...