之前几日,我先实现了用Python脚本导入XML文件到Elasticsearch中。现在我又写了一个初步的脚本,用elasticsearch框架实现了检索的功能,下面的想法可能是做成一个WEB端的检索系统,目前先实现相关的后端功能。
具体要求和思路
上面给的要求是输入有两种列表,除此之外不会有第三种序列:
- [str1,str2,······,strN] 这种列表的语义是str1OR str2 OR······strN
- [(str1,str2),(str3,str4),······(strN-1,strN)] 这种列表包含了元组,语义是(str1 AND str2) OR (str3 AND str4) OR ······ (strN-1 AND strN)
我的思路是先得判断输入是哪种序列,然后分别操作。我的思路是先判断列表里的元素是不是元组,如果是元组的话说明是第二种序列,反之则是第一种序列。具体实现如下:
# 如果列表里的元素是元组的话,说明是第二种序列
if isinstance(items, tuple):
# 操作第二种序列的数据
title_dict['match'].update({"title": items[0]})
title_dict['match'].update({"title": items[1]})
abstract_dict['match'].update({"abstract": items[0]})
abstract_dict['match'].update({"abstract": items[1]})
json_data_must["query"]["bool"]["must"].append(title_dict)
json_data_must["query"]["bool"]["must"].append(abstract_dict)
# 第二种序列标记为0,方便后续操作的判断
flag = 0
# 反之,说明是第一种序列
else:
# 操作第一种序列的数据
title_dict['match'].update({"title": items})
abstract_dict['match'].update({"abstract": items})
json_data_should["query"]["bool"]["should"].append(title_dict)
json_data_should["query"]["bool"]["should"].append(abstract_dict)
# 是第一种序列则标记为1,也是为了方便后续操作的判断
flag = 1
查阅了elasticsearch相关的书籍,我发现AND和OR的JSON串应该分别写成以下的样子,仅仅只是must和should的区别。由于是要匹配title和abstract,分开来写即可:
//AND语义的JSON串,使用must
{
"query": {
"bool": {
"must": [
{
"match": {
"abstract": {}
}
},
{
"match": {
"title": {}
}
},
]
}
}
}
//OR语义的JSON串,使用should
{
"query": {
"bool": {
"should": [
{
"match": {
"abstract": {}
}
},
{
"match": {
"title": {}
}
},
]
}
}
}
每次只要将类表里的数据按需填入字典abstract和字典title中就可以了。完整代码如下:
from pprint import pprint
from elasticsearch import Elasticsearch
def search(item_list):
flag = -1
es = Elasticsearch(hosts=['localhost:9200'])
index_name = "pubmed-paper-index"
json_data_must = {
"query": {
"bool": {
"must": [
]
}
}
}
json_data_should = {
"query": {
"bool": {
"should": [
]
}
}
}
for items in item_list:
title_dict = {
"match": {
"title": {}
}
}
abstract_dict = {
"match": {
"abstract": {}
}
}
if isinstance(items, tuple):
title_dict['match'].update({"title": items[0]})
title_dict['match'].update({"title": items[1]})
abstract_dict['match'].update({"abstract": items[0]})
abstract_dict['match'].update({"abstract": items[1]})
json_data_must["query"]["bool"]["must"].append(title_dict)
json_data_must["query"]["bool"]["must"].append(abstract_dict)
flag = 0
else:
title_dict['match'].update({"title": items})
abstract_dict['match'].update({"abstract": items})
json_data_should["query"]["bool"]["should"].append(title_dict)
json_data_should["query"]["bool"]["should"].append(abstract_dict)
flag = 1
# print(json_data)
# flag用于记录输入的哪种序列
if flag == 1:
res = es.search(index=index_name, body=json_data_should)
elif flag == 0:
res = es.search(index=index_name, body=json_data_must)
return res
if __name__ == "__main__":
list_items = ["ovalbumin"]
res = search(list_items)
pprint(res)
END