布尔查询
> 文档中心 > 文档中心 > INFINI Easysearch > 功能手册 > 搜索操作 > 布尔查询

布尔查询 #

bool 查询允许您将多个搜索查询与布尔逻辑结合起来。您可以在查询之间使用布尔逻辑来缩小或扩大搜索结果。

bool 查询是一个查询组合器,因为它允许您通过组合几个简单的查询来构造高级查询。

bool 查询中使用以下子句(子查询):

条件说明
must结果必须与此子句中的查询匹配。如果有多个查询,则每个查询都必须匹配。充当 and 运算符
must_not结果中排除所有匹配项。充当 not 运算符
should结果应该但不必与查询匹配。每个匹配的 should 子句都会增加相关性得分。作为选项,您可以要求一个或多个查询与 minimum_should_match 参数的值匹配(默认值为 1)
filter过滤器在应用查询之前减少数据集。筛选器子句中的查询是 yes-no 选项,其中如果文档与查询匹配,则将包含在结果中。筛选查询不会影响结果排序所依据的相关性分数。筛选查询的结果通常会被缓存,因此运行速度更快。使用筛选器查询根据精确匹配项、范围、日期、数字等筛选结果

bool 查询的结构如下:

GET _search
{
  "query": {
    "bool": {
      "must": [
        {}
      ],
      "must_not": [
        {}
      ],
      "should": [
        {}
      ],
      "filter": {}
    }
  }
}

例如,假设您有一个 Easysearch 集群中的莎士比亚全集索引。您希望构造满足以下要求的单个查询:

  1. text_entry 字段必须包含单词 love,并且应包含 lifegrace
  2. speaker 字段不能包含 ROMEO
  3. 将这些结果过滤到戏剧 Romeo and Juliet 中,而不影响相关性评分。

使用以下查询:

GET shakespeare/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "text_entry": "love"
          }
        }
      ],
      "should": [
        {
          "match": {
            "text_entry": "life"
          }
        },
        {
          "match": {
            "text_entry": "grace"
          }
        }
      ],
      "minimum_should_match": 1,
      "must_not": [
        {
          "match": {
            "speaker": "ROMEO"
          }
        }
      ],
      "filter": {
        "term": {
          "play_name": "Romeo and Juliet"
        }
      }
    }
  }
}

响应示例 #

{
  "took": 12,
  "timed_out": false,
  "_shards": {
    "total": 4,
    "successful": 4,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 11.356054,
    "hits": [
      {
        "_index": "shakespeare",
        "_type": "_doc",
        "_id": "88020",
        "_score": 11.356054,
        "_source": {
          "type": "line",
          "line_id": 88021,
          "play_name": "Romeo and Juliet",
          "speech_number": 19,
          "line_number": "4.5.61",
          "speaker": "PARIS",
          "text_entry": "O love! O life! not life, but love in death!"
        }
      }
    ]
  }
}

如果要确定这些子句中的哪一个实际上导致了匹配结果,请使用 _name 参数命名每个查询。

要添加 _name 参数,请将 match 查询中的字段名称更改为对象:

GET shakespeare/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "text_entry": {
              "query": "love",
              "_name": "love-must"
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "text_entry": {
              "query": "life",
              "_name": "life-should"
            }
          }
        },
        {
          "match": {
            "text_entry": {
              "query": "grace",
              "_name": "grace-should"
            }
          }
        }
      ],
      "minimum_should_match": 1,
      "must_not": [
        {
          "match": {
            "speaker": {
              "query": "ROMEO",
              "_name": "ROMEO-must-not"
            }
          }
        }
      ],
      "filter": {
        "term": {
          "play_name": "Romeo and Juliet"
        }
      }
    }
  }
}

Easysearch 返回一个 matched_queries 数组,其中列出了与这些结果匹配的查询:

"matched_queries": [
  "love-must",
  "life-should"
]

如果删除不在此列表中的查询,仍然会看到完全相同的结果。

通过检查匹配的 should 子句,您可以更好地了解结果的相关性得分。

您还可以通过嵌套 bool 查询来构造复杂的布尔表达式。

例如,要找到与剧中的( lovehate )AND( lifegrace )匹配的 text_entry 字段 Romeo and Juliet :

GET shakespeare/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "should": [
              {
                "match": {
                  "text_entry": "love"
                }
              },
              {
                "match": {
                  "text": "hate"
                }
              }
            ]
          }
        },
        {
          "bool": {
            "should": [
              {
                "match": {
                  "text_entry": "life"
                }
              },
              {
                "match": {
                  "text": "grace"
                }
              }
            ]
          }
        }
      ],
      "filter": {
        "term": {
          "play_name": "Romeo and Juliet"
        }
      }
    }
  }
}

响应示例 #

{
  "took": 10,
  "timed_out": false,
  "_shards": {
    "total": 2,
    "successful": 2,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 11.37006,
    "hits": [
      {
        "_index": "shakespeare",
        "_type": "doc",
        "_id": "88020",
        "_score": 11.37006,
        "_source": {
          "type": "line",
          "line_id": 88021,
          "play_name": "Romeo and Juliet",
          "speech_number": 19,
          "line_number": "4.5.61",
          "speaker": "PARIS",
          "text_entry": "O love! O life! not life, but love in death!"
        }
      }
    ]
  }
}