如何在Elasticsearch中生成查询并跳过部分查询?

时间:2017-02-16 21:12:32

标签: python elasticsearch

我使用Python通过自定义查询查询Elasticsearch。让我们看一个非常简单的例子,它将在字段'name'中搜索给定的术语,在文档的'surname'字段中搜索另一个术语:

from elasticsearch import Elasticsearch
import json
# read query from external JSON
with open('query.json') as data_file:    
    read_query= json.load(data_file)

# search with elastic search and show hits
es = Elasticsearch()
# set query through body parameter
res = es.search(index="test", doc_type="articles", body=read_query)
print("%d documents found" % res['hits']['total'])
for doc in res['hits']['hits']:
    print("%s) %s" % (doc['_id'], doc['_source']['content']))

'query.json'

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "Star",
              "boost": 2 
            }
          }
        },
        {
          "match": { 
            "surname": "Fox"
          }
        }
      ]
    }
  }
}

现在,我期待用户输入搜索词,输入的第一个词用于字段'name',第二个用于'surname'。让我们想象一下,我将用用户使用python输入的两个单词替换{$ name}和{$ surname}:

'query.json'

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "{$name}",
              "boost": 2 
            }
          }
        },
        {
          "match": { 
            "surname": "{$surname}"
          }
        }
      ]
    }
  }
}

现在当用户没有输入姓氏而只输入姓名时出现问题,所以我最终得到以下查询:

'query.json'

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "Star",
              "boost": 2 
            }
          }
        },
        {
          "match": { 
            "surname": ""
          }
        }
      ]
    }
  }
}

字段“surname”现在为空,elasticsearch将查找“surname”为空字符串的匹配,这不是我想要的。如果输入术语为空,我想忽略姓氏字段。如果给定的术语为空,弹性搜索中是否有任何机制可以将查询的一部分设置为忽略?

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "name": {
              "query": "Star",
              "boost": 2 
            }
          }
        },
        {
          "match": { 
            "surname": "",
            "ignore_if_empty" <--- this would be really cool
          }
        }
      ]
    }
  }
}

也许还有其他生成查询字符串的方法?我似乎无法在Elasticsearch中找到有关查询生成的任何信息。你们是怎么做到的?欢迎任何意见!

1 个答案:

答案 0 :(得分:0)

Python DSL似乎是正确的做法https://github.com/elastic/elasticsearch-dsl-py/