django基于sql的中文全文检索

   由于项目需求的原因,需要将检索结果通过提取出来转换为json的方式返回给中间层或前端。在笔记的检索中,如果通过检索所有的笔记,并再通过user_id去过滤数据时,会请求到很多不必要的数据,这并不是良好的设计,再加上项目需求中需要能够使用检索表达式来完成比较复杂的请求,于是考虑使用sql来进行功能的补充。
   具体的数据库设计等,见我的另一篇博客 https://blog.csdn.net/qq_37748146/article/details/90723891
   在这里需要满足基本的检索式需求(能够满足简单的布尔检索并进行拓展,即能够实现AND,OR查询,并可在OR关系的元素中使用AND查询)。
   注意这里使用空格来分隔查询关键词,即AND查询会将连续出现的且不为or的元素作为要同时查询的关键词。
   下面为几个查询例子

  • ‘A B ‘:满足A和B同时出现
  • ‘A or B ‘:满足A出现或者B出现
  • ‘A or B C ‘:满足出现A或者满足B和C同时出现
  • ‘A B or C D ‘:满足A和B同时出现或者满足C和D同时出现

编辑note/my_searchview.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def search_keywords(request):
if request.method == 'POST': # 当提交表单时
keywords = []
user_id = request.POST.get('user_id')
keyword = request.POST.get('keywords')
keyword1 = keyword.split('or') # 用来分隔需要满足AND查询的子查询集合
for i in range(len(keyword1)):
keyword2 = keyword1[i].split()
keywords.append(keyword2)
json_data = []
connection = sqlite3.connect('/home/projects/inspiration_notebook/db.sqlite3') # 服务器项目数据库文件
cursor = connection.cursor()
sql_list = []
for i in range(len(keywords)):
sql = "select * from note_note where user = " + str(user_id) + " and " \ #首先指定查询的用户
"( "
for j in range(len(keywords[i])):
sql_ = " (title like '%" + keywords[i][j] + \
"%' or notebook like '%" + keywords[i][j] + \
"%' or tag like '%" + keywords[i][j] + \
"%' or content like '%" + keywords[i][j] + "%' )"
sql_list.append(sql_) #这里拼接sql,例如查询'A B',需要满足A与B同时出现

for m in range(len(sql_list)):
sql += sql_list[m] + 'or' if m != len(sql_list) - 1 else sql_list[m]
sql += ")" #这里拼接sql,满足通过or分隔的多组查询关键词
result = cursor.execute(sql).fetchall()
for i in range(len(result)):
note_data = {
'title': result[i][1],
'user_id': result[i][2],
'content': result[i][3],
'tag': result[i][4],
'notebook': result[i][5],
}
if not note_data in json_data:
json_data.append(note_data)
print(json_data)
code = 200
msg = 'successful'
result = {"code": code, "msg": msg, "data": json_data}
# 关键步骤:转化为json格式,并返回给前端
return HttpResponse(json.dumps(result, ensure_ascii=False), content_type="application/json,charset=utf-8")
else:
result = {"code": 414, "msg": 'failed', "data": '请使用POST请求'} #注意,这里的code指的并不是http返回码,而是项目自身规定的返回码。
return HttpResponse(json.dumps(result), content_type="application/json")

这样就可以得到某一个用户下满足需求的笔记了,减少了很多不必要的变量。并将json形式的数据返回给中间层或前端。