elasticsearch - support - query filter
elasticsearch bool query combine debe con O (5)
Actualmente estoy intentando migrar una aplicación basada en solr a elasticsearch.
Tengo esta consulta lucene
((
name:(+foo +bar)
OR info:(+foo +bar)
)) AND state:(1) AND (has_image:(0) OR has_image:(1)^100)
Por lo que yo entiendo, esta es una combinación de cláusulas MUST combinadas con OR booleana:
"Obtenga todos los documentos que contengan (foo AND bar en el nombre) O (foo AND bar en la información). Después de ese filtro, se obtendrá el estado de condición = 1 y se impulsarán los documentos que tengan una imagen".
He estado tratando de usar una consulta bool con DEBE pero no puedo obtener booleano O en cláusulas obligatorias. Esto es lo que tengo:
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 puede ver, faltan las condiciones de "información".
¿Alguien tiene una solución?
Muchas gracias.
** ACTUALIZACIÓN **
He actualizado mi consulta elasticsearch y me deshice de esa puntuación de función. Mi problema base todavía existe.
Finalmente logré crear una consulta que hace exactamente lo que quería:
Una consulta booleana anidada filtrada. No estoy seguro de por qué esto no está documentado. Tal vez alguien aquí puede decirme?
Aquí está la consulta:
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
}
}
}
}
}
En pseudo-SQL:
SELECT * FROM /test/object
WHERE
((name=foo AND name=bar) OR (info=foo AND info=bar))
AND state=1
Tenga en cuenta que depende de su análisis de campo de documentos y asignaciones cómo se maneja internamente name = foo. Esto puede variar de un comportamiento difuso a estricto.
"minimum_should_match": 1 dice que al menos una de las declaraciones debe ser verdadera.
Esta afirmación significa que cada vez que hay un documento en el conjunto de resultados que contiene has_image: 1 es aumentado por el factor 100. Esto cambia el orden de los resultados.
"should": [
{
"match": {
"has_image": {
"query": 1,
"boost": 100
}
}
}
]
Diviértete chicos :)
Recientemente tuve que resolver este problema también, y después de MUCHO ensayo y error, se me ocurrió esto (en PHP, pero se asigna directamente a la 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 se asigna a algo como esto en 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>
La clave en todo esto es la configuración minimum_should_match
. Sin esto, el filter
anula por completo el should
.
¡Espero que esto ayude a alguien!
Usando lo anterior, obtengo
[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
Esto funcionó para mí
Actualizado para Elasticsearch 5.6.4 +
{
"query": {
"bool": {
"must": [
{"term": {"shape": "round"}},
{"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}}
]
}}
]
}
}
}
$filterQuery = $this->queryFactory->create(QueryInterface::TYPE_BOOL, [''must'' => $queries,''should''=>$queriesGeo]);
En must
, debe agregar el conjunto de condiciones de consulta con el que desea trabajar AND
y en should
que necesite agregar la condición de consulta con la que desea trabajar OR
Puede verificar esto: https://github.com/Smile-SA/elasticsuite/issues/972
- O se escribe "debería"
- Y se deletrea "debe"
- NOR se deletrea "should_not"
Ejemplo:
Desea ver todos los elementos que son (redondos Y (rojo O azul)):
{
"query": {
"bool": {
"must": [
{
"term": {"shape": "round"},
"bool": {
"should": [
{"term": {"color": "red"}},
{"term": {"color": "blue"}}
]
}
}
]
}
}
}
También puede hacer versiones más complejas de O, por ejemplo, si desea hacer coincidir al menos 3 de 5, puede especificar 5 opciones en "debería" y establecer un "minimum_should" de 3.