实习工作复盘·用Elasticsearch的Python的API实现搜索功能

之前几日,我先实现了用Python脚本导入XML文件到Elasticsearch中。现在我又写了一个初步的脚本,用elasticsearch框架实现了检索的功能,下面的想法可能是做成一个WEB端的检索系统,目前先实现相关的后端功能。

具体要求和思路

上面给的要求是输入有两种列表,除此之外不会有第三种序列:

  1. [str1,str2,······,strN]   这种列表的语义是str1OR str2 OR······strN
  2. [(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

猜你喜欢

转载自blog.csdn.net/qq_41938259/article/details/123672357