J'interroge un index élastique avec 300 enregistrements en utilisant la requête composée comme ci-dessous:

GET my_index/_search
{
  "size": 10,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "should": [
              {
                "multi_match": {
                  "query": "card",
                  "fields": [
                    "title^1.0"
                  ]
                }
              }
            ],
            "must": {
              "term": {
                  "_index": {
                    "value": "my_index"
                  }
                }
            }
          }
        }
      ]
    }
  }
}

Le must sur l'index est que cela pourrait être une requête multi-index selon une logique métier (doit probablement être un filtre, et je peux changer cela, mais ce n'est pas la partie de ma question. J'obtiens les mêmes résultats avec le filtre que bien).

Alors que je m'attends à ce que cela renvoie les documents qui correspondent à la clause should, je récupère tous les documents de l'index (300)

Pourquoi cela arriverait-il?

1
ishan aggarwal 25 août 2020 à 00:32

2 réponses

Meilleure réponse

La résolution de ce problème était d'ajouter le champ minimumShouldMatch à la requête. La requête résultante devient alors:

GET my_index/_search
{
  "size": 10,
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "multi_match": {
                  "query": "card",
                  "fields": [
                    "title^1.0"
                  ]
                }
              }
            ],
            "must": {
              "term": {
                  "_index": {
                    "value": "my_index"
                  }
                }
            }
          }
        }
      ]
    }
  }
}

Le raisonnement derrière cela, je crois, est que la requête booléenne est réglée pour donner le nombre maximum de résultats correspondants (plus de correspondances, c'est mieux). Donc, si la clause must / filter correspond, should n'est même pas exécuté. En ajoutant "minimum_should_match": 1, nous demandons à elasticsearch de faire correspondre au moins 1 clause should avant de renvoyer le document.

Extraits de la documentation élastique:

La requête booléenne adopte une approche plus de correspondances est meilleure, de sorte que le score de chaque clause must ou should correspondante sera additionné pour fournir le _score final pour chaque document.

Vous pouvez utiliser le paramètre minimum_should_match pour spécifier le nombre ou le pourcentage de clauses should que les documents renvoyés doivent correspondre.

Si la requête booléenne comprend au moins une clause should et aucune clause must ou filter, la valeur par défaut est 1. Sinon, la valeur par défaut est 0.

Pour d'autres valeurs valides, consultez le paramètre minimum_should_match.

Lien de référence - https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html#bool-min-should-match

1
ishan aggarwal 28 août 2020 à 16:13

Ajout d'un exemple de travail avec des données d'index et une requête de recherche

Données d'index:

{
    "title":"card",
    "cost":"55"
}
{
    "title":"Card making",
    "cost":"55"
}
{
    "title":"elasticsearch",
    "cost":"55"
}

Requête de recherche:

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "filter": [
              {
                "term": {
                  "_index": {
                    "value": "index-name"
                  }
                }
              }
            ],
            "must": [
              {
                "multi_match": {
                  "fields": [
                    "title^1.0"
                  ],
                  
                  "query": "card"
                }
              }
            ]
          }
        }
      ]
    }
  }
}

Résultat de la recherche:

"hits": [
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "1",
        "_score": 0.7549127,
        "_source": {
          "title": "card",
          "cost": "55"
        }
      },
      {
        "_index": "my_index",
        "_type": "_doc",
        "_id": "2",
        "_score": 0.55654144,
        "_source": {
          "title": "Card making",
          "cost": "55"
        }
      }
    ]
0
ESCoder 25 août 2020 à 04:06