码迷,mamicode.com
首页 > 数据库 > 详细

Python札记 -- MongoDB模糊查询

时间:2014-07-30 17:10:54      阅读:407      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   使用   os   io   数据   问题   

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

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

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 
 4 import re
 5 import mongoengine
 6 from mongoengine import *
 7 
 8 mongoengine.register_connection(default, test, host=127.0.0.1)
 9 
10 class TestData(Document):
11     name = StringField()
12     content = StringField()
13 
14 TestData.objects.get_or_create(name=天地玄黄,defaults={content:abc123})
15 TestData.objects.get_or_create(name=宇宙洪荒,defaults={content:ABC123})
16 TestData.objects.get_or_create(name=天天向上,defaults={content:Abc123})
17 
18 def print_arr(obj):
19     print obj.name,obj.content
20 
21 def fuzzy_query_by_contains():
22     print "\n###使用mongoengine的contains进行查询"
23     print "#contains区分大小写:"
24     test_data_list = TestData.objects(content__contains=abc123)
25     map(print_arr,test_data_list)
26 
27     print "#icontains不区分大小写:"
28     test_data_list = TestData.objects(content__icontains=abc123)
29     map(print_arr,test_data_list)
30 
31 def fuzzy_query_by_Q():
32     print "\n###使用Q来进行查询"
33     test_data_list = TestData.objects(
34         Q(name__icontains=u天地) | Q(name__icontains=u宇宙))
35     map(print_arr,test_data_list)
36 
37 def fuzzy_query_by_pymongo():
38     print "\n###使用raw queries,New in version 0.4"
39     print "#单个查询条件"
40     search = {
41         __raw__:{
42             content:{$regex:A\S+\d+},
43         },
44     }
45     test_data_list = TestData.objects(**search)
46     map(print_arr,test_data_list)
47 
48     print "#多个查询条件"
49     search = {
50         __raw__:{
51             name:{$in:[re.compile(u天天),re.compile(u宇宙)]},
52         },
53     }
54     test_data_list = TestData.objects(**search)
55     map(print_arr,test_data_list)
56 
57 if __name__ == __main__:
58     fuzzy_query_by_contains()
59     fuzzy_query_by_Q()
60     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‘宇宙‘)]}

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

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

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

1 >>> a, created = User.objects.get_or_create(name=User A, defaults={age: 30})
2 >>> b, created = User.objects.get_or_create(name=User A, defaults={age: 40})
3 >>> a.name == b.name and a.age == b.age
4 True

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

 1 $ python mongodb_test.py
 2 
 3 ###使用mongoengine的contains进行查询
 4 #contains区分大小写:
 5 天地玄黄 abc123
 6 #icontains不区分大小写:
 7 天地玄黄 abc123
 8 宇宙洪荒 ABC123
 9 天天向上 Abc123
10 
11 ###使用Q来进行查询
12 天地玄黄 abc123
13 宇宙洪荒 ABC123
14 
15 ###使用raw queries,New in version 0.4
16 #单个查询条件
17 宇宙洪荒 ABC123
18 天天向上 Abc123
19 #多个查询条件
20 宇宙洪荒 ABC123
21 天天向上 Abc123

 

Python札记 -- MongoDB模糊查询,布布扣,bubuko.com

Python札记 -- MongoDB模糊查询

标签:style   blog   color   使用   os   io   数据   问题   

原文地址:http://www.cnblogs.com/PandaBamboo/p/3878237.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!