pesquisa elastica bool query combine must com ou
tenho esta pergunta lucene
((
name:(+foo +bar)
OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)
Tanto quanto sei, trata-se de uma combinação de cláusulas obrigatórias combinadas com cláusulas booleanas ou:
"obter todos os documentos que contenham (foo e bar em nome) ou (foo e bar em informação). Depois que o filtro resulta por estado de condição=1 e impulsionar documentos que têm uma imagem."
eu tenho tentado usar uma consulta bool com MUST mas eu estou falhando em obter boolean ou em must clauses. Eis o que tenho:
GET /test/object/_search
{
"from": 0,
"size": 20,
"sort": {
"_score": "desc"
},
"query": {
"bool": {
"must": [
{
"match": {
"name": "foo"
}
},
{
"match": {
"name": "bar"
}
}
],
"must_not": [],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
}
}
Como pode ver, faltam as condições necessárias para" info".
Alguém tem uma solução? Muito obrigado.** Actualizar * *
actualizei a minha pesquisa elastica e livrei-me desse resultado de funções. O meu problema básico ainda existe.
6 answers
- ou escreve-se"deve"
- e escreve-se"must"
- nem se escreve "should_not"
Exemplo:
Você quer ver todos os itens que são (redondos e (vermelho ou azul)):
{
"query": {
"bool": {
"must": [
{
"term": {"shape": "round"},
},
{
"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}}
]
}
}
]
}
}
}
Você também pode fazer versões mais complexas de ou, por exemplo, se quiser corresponder pelo menos 3 em 5, você pode especificar 5 opções em "DEVE" e definir um "minimum_ should" de 3.
Obrigado ao Glen Thompson e ao Sebastialonso por descobrirem onde é o meu ninho. não estava certo antes.Obrigado também ao Fatmajk por apontar que "termo" se torna "compatível" na ElasticSearch 6.
Uma pesquisa booleana filtrada. Não sei por que razão isto não está documentado. Talvez alguém aqui me possa dizer?
Aqui está a Pergunta:
GET /test/object/_search
{
"from": 0,
"size": 20,
"sort": {
"_score": "desc"
},
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"state": 1
}
}
]
}
},
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": {
"name": "foo"
}
},
{
"match": {
"name": "bar"
}
}
],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"info": "foo"
}
},
{
"match": {
"info": "bar"
}
}
],
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
}
}
],
"minimum_should_match": 1
}
}
}
}
}
Em pseudo-SQL:
SELECT * FROM /test/object
WHERE
((name=foo AND name=bar) OR (info=foo AND info=bar))
AND state=1
Por favor, tenha em mente que depende da sua análise de campo do documento e mapeamentos como o nome=foo é tratado internamente. Isto pode variar de um comportamento difuso a estrito.
"minimum_ should_ match": 1 diz, que pelo menos uma das declarações deve ser verdade.
Estas declarações significam que sempre que existe um documento no conjunto de resultados que contém has_image:1 é reforçado pelo factor 100. Isto muda a ordenação do resultado.
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
Divirtam-se.
Usando o acima eu fico
[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
Actualizado para a pesquisa elastica 5. 6. 4 +
{
"query": {
"bool": {
"must": [
{"term": {"shape": "round"}},
{"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}}
]
}}
]
}
}
}
Recentemente eu tive que resolver este problema também, e depois de um monte de tentativa e erro eu cheguei com isso (em PHP, mas mapeia diretamente para o DSL):
'query' => [
'bool' => [
'should' => [
['prefix' => ['name_first' => $query]],
['prefix' => ['name_last' => $query]],
['prefix' => ['phone' => $query]],
['prefix' => ['email' => $query]],
[
'multi_match' => [
'query' => $query,
'type' => 'cross_fields',
'operator' => 'and',
'fields' => ['name_first', 'name_last']
]
]
],
'minimum_should_match' => 1,
'filter' => [
['term' => ['state' => 'active']],
['term' => ['company_id' => $companyId]]
]
]
]
Que mapeia para algo como isto em SQL:
SELECT * from <index>
WHERE (
name_first LIKE '<query>%' OR
name_last LIKE '<query>%' OR
phone LIKE '<query>%' OR
email LIKE '<query>%'
)
AND state = 'active'
AND company_id = <query>
A chave em tudo isto é a configuração minimum_should_match
. Sem isto, o filter
sobrepõe-se totalmente ao should
.
Conversor de SQL para ElasticSearch
Podes agradecer-me mais tarde.$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, ['must' => $queries,'should'=>$queriesGeo]);
Em must
tem de adicionar a lista de condições da consulta com a qual deseja trabalhar AND
e em should
tem de adicionar a condição da pesquisa com a qual deseja trabalhar OR
.
Podes verificar isto: https://github.com/Smile-SA/elasticsuite/issues/972