工做开始,觉得是很简单的需求,因此直接用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.