弹性搜索中的查询与过滤器

时间:2018-10-29 20:06:41

标签: elasticsearch

我正在尝试索引一个文档,该文档具有first_name,last_name,“ keyword”类型的三个字段,并且分别具有值XYZ,ABC和DEF。

我已经使用过滤器编写了与AND条件完全匹配的查询,如下所示:

"query": {
  "bool": {
    "filter": [
      {"term": {"first_name": "XYZ"}},
      {"term": {"last_name": "ABC"}}
    ]
  }
}

这必须返回一个文档,但是什么也不返回。

我对同一操作有另一个查询,

"query": {
  "bool": {
    "must": [
      {"match": {"first_name": "XYZ"}},
      {"match": {"last_name": "ABC"}}
    ]
  }
}

这将返回一个文档。

根据Elasticsearch文档,我了解查询和过滤器之间的区别在于过滤器不会对结果进行评分。我不确定为什么第一个查询不返回任何结果。我的理解正确吗?

1 个答案:

答案 0 :(得分:1)

正如文档所述,除计分外,查询和过滤器之间没有区别。当然,这适用于查询和过滤器使用相同查询类型的情况。在这里,您使用两种不同的类型-termmatchterm用于精确比较,而match被分析并用作全文搜索。

看看下面的例子。

您的映射:

PUT /index_53053054
{
  "mappings": {
    "_doc": {
      "properties": {
        "first_name": {
          "type": "text"
        },
        "last_name": {
          "type": "text"
        },
        "occupation": {
          "type": "keyword"
        }
      }
    }
  }
}

您的文档:

PUT index_53053054/_doc/1
{
  "first_name": "XYZ",
  "last_name": "ABC",
  "occupation": "DEF"
}

filter查询:

GET index_53053054/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "match": {
            "first_name": "XYZ"
          }
        },
        {
          "match": {
            "last_name": "ABC"
          }
        },
        {
          "term": {
            "occupation": "DEF"
          }
        }
      ]
    }
  }
}

和结果:

{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0,
    "hits": [
      {
        "_index": "index_53053054",
        "_type": "_doc",
        "_id": "1",
        "_score": 0,
        "_source": {
          "first_name": "XYZ",
          "last_name": "ABC",
          "occupation": "DEF"
        }
      }
    ]
  }
}

类似的must查询:

GET index_53053054/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "first_name": "XYZ"
          }
        },
        {
          "match": {
            "last_name": "ABC"
          }
        },
        {
          "term": {
            "occupation": "DEF"
          }
        }
      ]
    }
  }
}

和响应:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.8630463,
    "hits": [
      {
        "_index": "index_53053054",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.8630463,
        "_source": {
          "first_name": "XYZ",
          "last_name": "ABC",
          "occupation": "DEF"
        }
      }
    ]
  }
}

您可以看到hits几乎相同。唯一的区别是,在filter查询中不计算分数,而在must查询中则不计算分数。

了解更多:https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-filter-context.html