Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Query DSL ›Compound queries

Запрос Boolean

Запрос, который сопоставляет документы, соответствующие логическим комбинациям других запросов. Запрос bool сопоставляется с Lucene BooleanQuery. Он построен с использованием одного или нескольких логических условий, каждое с типом совпадения. Типы совпадения:

Occur Описание

must

Условие (запрос) должно присутствовать в соответствующих документах и будет вносить вклад в рейтинг. Каждый запрос, определённый под must, действует как логическое «И», возвращая только документы, соответствующие всем указанным запросам.

should

Условие (запрос) должно присутствовать в соответствующем документе. Каждый запрос, определённый под should, действует как логическое «ИЛИ», возвращая документы, соответствующие любому из указанных запросов.

filter

Условие (запрос) должно присутствовать в соответствующих документах. Однако, в отличие от must, рейтинг запроса будет игнорироваться. Фильтрующие условия выполняются в контексте фильтра, что означает, что рейтинг игнорируется, и условия учитываются для кэширования. Каждый запрос, определённый под filter, действует как логическое «И», возвращая только документы, соответствующие всем указанным запросам.

must_not

Условие (запрос) не должно присутствовать в соответствующих документах. Условия выполняются в контексте фильтра, что означает, что рейтинг игнорируется, и условия учитываются для кэширования. Поскольку рейтинг игнорируется, для всех документов возвращается рейтинг 0. Каждый запрос, определённый под must_not, действует как логическое «НЕ», возвращая только документы, не соответствующие ни одному из указанных запросов.

Условные must и should элементы работают как логические операторы «И» и «ИЛИ», внося вклад в рейтинг результатов. Однако эти результаты не будут кэшироваться для ускорения поиска. В отличие от них, условия filter и must_not используются для включения или исключения результатов без влияния на рейтинг, если не используются в запросе constant_score.

Запрос bool использует подход «больше совпадений — лучше рейтинг», поэтому рейтинг каждого совпадающего условия must или should будет суммироваться для получения итогового рейтинга _score для каждого документа.

resp = client.search(
    query={
        "bool": {
            "must": {
                "term": {
                    "user.id": "kimchy"
                }
            },
            "filter": {
                "term": {
                    "tags": "production"
                }
            },
            "must_not": {
                "range": {
                    "age": {
                        "gte": 10,
                        "lte": 20
                    }
                }
            },
            "should": [
                {
                    "term": {
                        "tags": "env1"
                    }
                },
                {
                    "term": {
                        "tags": "deployed"
                    }
                }
            ],
            "minimum_should_match": 1,
            "boost": 1
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      bool: {
        must: {
          term: {
            'user.id' => 'kimchy'
          }
        },
        filter: {
          term: {
            tags: 'production'
          }
        },
        must_not: {
          range: {
            age: {
              gte: 10,
              lte: 20
            }
          }
        },
        should: [
          {
            term: {
              tags: 'env1'
            }
          },
          {
            term: {
              tags: 'deployed'
            }
          }
        ],
        minimum_should_match: 1,
        boost: 1
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    bool: {
      must: {
        term: {
          "user.id": "kimchy",
        },
      },
      filter: {
        term: {
          tags: "production",
        },
      },
      must_not: {
        range: {
          age: {
            gte: 10,
            lte: 20,
          },
        },
      },
      should: [
        {
          term: {
            tags: "env1",
          },
        },
        {
          term: {
            tags: "deployed",
          },
        },
      ],
      minimum_should_match: 1,
      boost: 1,
    },
  },
});
console.log(response);
POST _search
{
  "query": {
    "bool" : {
      "must" : {
        "term" : { "user.id" : "kimchy" }
      },
      "filter": {
        "term" : { "tags" : "production" }
      },
      "must_not" : {
        "range" : {
          "age" : { "gte" : 10, "lte" : 20 }
        }
      },
      "should" : [
        { "term" : { "tags" : "env1" } },
        { "term" : { "tags" : "deployed" } }
      ],
      "minimum_should_match" : 1,
      "boost" : 1.0
    }
  }
}

Использование minimum_should_match

Вы можете использовать параметр minimum_should_match для указания количества или процента условий should, которым документы должны соответствовать.

Если запрос bool включает по крайней мере одно условие should и не содержит условий must или filter, значение по умолчанию — 1. В противном случае значение по умолчанию — 0.

Другие допустимые значения см. в параметре minimum_should_match.

Рейтинг с bool.filter

Запросы, указанные в элементе filter, не влияют на рейтинг — возвращаются значения рейтинга 0. Рейтинг зависит только от указанного запроса. Например, все три следующих запроса возвращают все документы, где поле status содержит термин active.

В первом запросе всем документам присваивается рейтинг 0, так как не указан запрос рейтингов:

$params = [
    'body' => [
        'query' => [
            'bool' => [
                'filter' => [
                    'term' => [
                        'status' => 'active',
                    ],
                ],
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    query={
        "bool": {
            "filter": {
                "term": {
                    "status": "active"
                }
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      bool: {
        filter: {
          term: {
            status: 'active'
          }
        }
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "bool": {
	      "filter": {
	        "term": {
	          "status": "active"
	        }
	      }
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    bool: {
      filter: {
        term: {
          status: "active",
        },
      },
    },
  },
});
console.log(response);
GET _search
{
  "query": {
    "bool": {
      "filter": {
        "term": {
          "status": "active"
        }
      }
    }
  }
}

В этом запросе bool есть запрос match_all, который присваивает всем документам рейтинг 1.0.

$params = [
    'body' => [
        'query' => [
            'bool' => [
                'must' => [
                    'match_all' => [
                    ],
                ],
                'filter' => [
                    'term' => [
                        'status' => 'active',
                    ],
                ],
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    query={
        "bool": {
            "must": {
                "match_all": {}
            },
            "filter": {
                "term": {
                    "status": "active"
                }
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      bool: {
        must: {
          match_all: {}
        },
        filter: {
          term: {
            status: 'active'
          }
        }
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "bool": {
	      "must": {
	        "match_all": {}
	      },
	      "filter": {
	        "term": {
	          "status": "active"
	        }
	      }
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    bool: {
      must: {
        match_all: {},
      },
      filter: {
        term: {
          status: "active",
        },
      },
    },
  },
});
console.log(response);
GET _search
{
  "query": {
    "bool": {
      "must": {
        "match_all": {}
      },
      "filter": {
        "term": {
          "status": "active"
        }
      }
    }
  }
}

Этот запрос constant_score ведет себя точно так же, как второй пример выше. Запрос constant_score присваивает рейтинг 1.0 всем документам, соответствующим фильтру.

$params = [
    'body' => [
        'query' => [
            'constant_score' => [
                'filter' => [
                    'term' => [
                        'status' => 'active',
                    ],
                ],
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    query={
        "constant_score": {
            "filter": {
                "term": {
                    "status": "active"
                }
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      constant_score: {
        filter: {
          term: {
            status: 'active'
          }
        }
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "constant_score": {
	      "filter": {
	        "term": {
	          "status": "active"
	        }
	      }
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  query: {
    constant_score: {
      filter: {
        term: {
          status: "active",
        },
      },
    },
  },
});
console.log(response);
GET _search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "status": "active"
        }
      }
    }
  }
}

Именованные запросы

Каждый запрос принимает _name в своём верхнем уровне определения. Вы можете использовать именованные запросы для отслеживания, какие запросы соответствовали возвращённым документам. Если используются именованные запросы, ответ содержит свойство matched_queries для каждого совпадения.

Предоставление дублирующих значений _name в одном запросе приводит к неопределённому поведению. Запросы с одинаковыми именами могут перезаписывать друг друга. Имена запросов считаются уникальными в рамках одного запроса.

resp = client.search(
    query={
        "bool": {
            "should": [
                {
                    "match": {
                        "name.first": {
                            "query": "shay",
                            "_name": "first"
                        }
                    }
                },
                {
                    "match": {
                        "name.last": {
                            "query": "banon",
                            "_name": "last"
                        }
                    }
                }
            ],
            "filter": {
                "terms": {
                    "name.last": [
                        "banon",
                        "kimchy"
                    ],
                    "_name": "test"
                }
            }
        }
    },
)
print(resp)
response = client.search(
  body: {
    query: {
      bool: {
        should: [
          {
            match: {
              'name.first' => {
                query: 'shay',
                _name: 'first'
              }
            }
          },
          {
            match: {
              'name.last' => {
                query: 'banon',
                _name: 'last'
              }
            }
          }
        ],
        filter: {
          terms: {
            'name.last' => [
              'banon',
              'kimchy'
            ],
            _name: 'test'
          }
        }
      }
    }
  }
)
puts response
const response = await client.search({
  query: {
    bool: {
      should: [
        {
          match: {
            "name.first": {
              query: "shay",
              _name: "first",
            },
          },
        },
        {
          match: {
            "name.last": {
              query: "banon",
              _name: "last",
            },
          },
        },
      ],
      filter: {
        terms: {
          "name.last": ["banon", "kimchy"],
          _name: "test",
        },
      },
    },
  },
});
console.log(response);
GET /_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "name.first": { "query": "shay", "_name": "first" } } },
        { "match": { "name.last": { "query": "banon", "_name": "last" } } }
      ],
      "filter": {
        "terms": {
          "name.last": [ "banon", "kimchy" ],
          "_name": "test"
        }
      }
    }
  }
}

Параметр запроса с именем include_named_queries_score управляет тем, возвращаются ли оценки, связанные с соответствующими запросами. При установке параметра ответ включает карту matched_queries, которая содержит имя совпавшего запроса в качестве ключа и связанную с ним оценку в качестве значения.

Обратите внимание, что оценка может не повлиять на итоговую оценку документа, например, именованные запросы, которые появляются в контекстах фильтра или must_not, или внутри условий, которые игнорируют или изменяют оценку, таких как constant_score или function_score_query.

resp = client.search(
    include_named_queries_score=True,
    query={
        "bool": {
            "should": [
                {
                    "match": {
                        "name.first": {
                            "query": "shay",
                            "_name": "first"
                        }
                    }
                },
                {
                    "match": {
                        "name.last": {
                            "query": "banon",
                            "_name": "last"
                        }
                    }
                }
            ],
            "filter": {
                "terms": {
                    "name.last": [
                        "banon",
                        "kimchy"
                    ],
                    "_name": "test"
                }
            }
        }
    },
)
print(resp)
response = client.search(
  include_named_queries_score: true,
  body: {
    query: {
      bool: {
        should: [
          {
            match: {
              'name.first' => {
                query: 'shay',
                _name: 'first'
              }
            }
          },
          {
            match: {
              'name.last' => {
                query: 'banon',
                _name: 'last'
              }
            }
          }
        ],
        filter: {
          terms: {
            'name.last' => [
              'banon',
              'kimchy'
            ],
            _name: 'test'
          }
        }
      }
    }
  }
)
puts response
const response = await client.search({
  include_named_queries_score: "true",
  query: {
    bool: {
      should: [
        {
          match: {
            "name.first": {
              query: "shay",
              _name: "first",
            },
          },
        },
        {
          match: {
            "name.last": {
              query: "banon",
              _name: "last",
            },
          },
        },
      ],
      filter: {
        terms: {
          "name.last": ["banon", "kimchy"],
          _name: "test",
        },
      },
    },
  },
});
console.log(response);
GET /_search?include_named_queries_score
{
  "query": {
    "bool": {
      "should": [
        { "match": { "name.first": { "query": "shay", "_name": "first" } } },
        { "match": { "name.last": { "query": "banon", "_name": "last" } } }
      ],
      "filter": {
        "terms": {
          "name.last": [ "banon", "kimchy" ],
          "_name": "test"
        }
      }
    }
  }
}

Эта функциональность повторно выполняет каждый именованный запрос для каждой записи в ответе поиска. Как правило, это добавляет небольшую нагрузку на запрос. Однако использование вычислительно сложных именованных запросов на большом количестве записей может добавить значительную нагрузку. Например, именованные запросы в сочетании с агрегацией top_hits по многим корзинам могут привести к увеличению времени ответа.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/query-dsl-bool-query.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API