Python劄記 -- MongoDB模糊查詢

來源:互聯網
上載者:User

標籤: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.content20 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,提供了兩種方法,一種是使用$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.age4 True

    最後是例子啟動並執行結果,返回的結果順序可能略有不同,不必在意。

 1 $ python mongodb_test.py 2  3 ###使用mongoengine的contains進行查詢 4 #contains區分大小寫: 5 天地玄黃 abc123 6 #icontains不區分大小寫: 7 天地玄黃 abc123 8 宇宙洪荒 ABC123 9 天天向上 Abc12310 11 ###使用Q來進行查詢12 天地玄黃 abc12313 宇宙洪荒 ABC12314 15 ###使用raw queries,New in version 0.416 #單個查詢條件17 宇宙洪荒 ABC12318 天天向上 Abc12319 #多個查詢條件20 宇宙洪荒 ABC12321 天天向上 Abc123

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.