工做記錄:一個模糊匹配關鍵詞搜索的功能需求

    工做開始,覺得是很簡單的需求,因此直接用django的orm提供的contains方法進行的搜索處理。python

images = Image.objects.filter(tips__contains=key)[(page-1)*count:page*count]

    經過打印sql查看,這句會生成以下:sql

    SELECT * FROM `image` WHERE `image`.`tips` LIKE BINARY '%我要吃飯%';(將參數用*代替了)數據庫

    但這個只能搜索到image記錄的tips包含「我要吃飯」的記錄。而需求是若是輸入的是「我要吃飯」, 那麼應該返回包含‘我要’, ‘吃飯’的記錄。django

    這裏好像是須要天然語言處理的方面吧,本人沒有研究過,但放倒這個需求中,個人考慮是直接將傳遞進來的key分割成len()大於等於2的詞組(需求上不用考慮英文)。而後將這些詞組都進行contains處理,中間用or關係連接。json

    先是實現分割詞組:數組

def getWordsByKey(key):
   result = [key,]
   if len(key) > 2:
      result += getWordsByKey(key[1:])
      result += getWordsByKey(key[:-1])
   return list(set(result))

    這裏用了迭代的方式便可將傳入的key切割成須要的詞組數組。app

    而後or的關係在django中能夠用Q來實現,可是這時我並不知道返回的這個關鍵字數字有多少個,很差用這種方式去直接實現。
測試

    到這裏,我準備直接本身拼湊sql去實現,正好,以前看到了一個django 的orm方法raw,https://docs.djangoproject.com/en/1.9/ref/models/querysets/#raw, 因此準備嘗試用raw,若是能夠的話,它能夠幫助我將數據庫中查找到的數據轉成業務上Image的對象。url

    先循環以前獲取到的關鍵字列表構造須要的sql語句:
spa

keys = getWordsByKey(key)
sql = "SELECT id,name,hot_level,url,img_set_id,is_hot,is_new,use_count,from_way, tips   FROM image WHERE "
keys_len = len(keys)
for index, each in enumerate(keys):
   sql += u" tips LIKE BINARY '%%"+each+"%%'"
   if index < keys_len - 1:
      sql += ' or '

    而後使用raw執行sql語句:

images = Image.objects.raw(sql)
for each in images:
   imgs_data.append(each.tojson())

    測試可以正常獲得須要的功能。 

end.

相關文章
相關標籤/搜索