Puzzle de filtrage des requêtes Elasticsearch

introduction

J'ai été confus par la requête et le filtre auparavant, pourquoi le même booléen est une requête à un endroit et un filtre à un autre.

Plus tard, j'ai examiné de plus près les documents officiels et j'ai découvert qu'il s'agissait de requêtes, en distinguant simplement:

  1. contexte de requête
  2. contexte de filtre

Pourquoi faire la distinction entre le contexte de requête et le contexte de filtre?

Étant donné que l'efficacité est différente, la requête dans le contexte de filtre est plus efficace , car le contexte de filtre ne calcule pas le score de pertinence, et ES mettra automatiquement en cache les requêtes de filtrage haute fréquence.

Quel est le contexte de filtrage

Tout d'abord, je vois que le filtre doit être, et le must_not dans la requête booléenne sera également exécuté dans le contexte du filtre.

filtre

requête booléenne:

{
    
    
  "query": {
    
     
    "bool": {
    
     
      "filter": [ 
        {
    
     "term":  {
    
     "status": "1" }},
        {
    
     "range": {
    
     "create_date": {
    
     "lte": "2020-01-01" }}}
      ]
    }
  }
}

requête constant_score:

{
    
    
    "query": {
    
    
        "constant_score" : {
    
    
            "filter" : {
    
    
                "term" : {
    
     "user" : "tim"}
            },
            "boost" : 1.2
        }
    }
}

Dans la fonction d'agrégation:

{
    
    
  "aggs" : {
    
    
      "month" : {
    
    
          "filter" : {
    
     "term": {
    
     "type": "2" } }
      }
  }
}

ne doit pas

{
    
    
  "query": {
    
    
    "bool" : {
    
    
      "must_not" : {
    
    
        "range" : {
    
    
          "age" : {
    
     "gte" : 18, "lte" : 30 }
        }
      }
    }
  }
}

requête booléenne

Types de La description
doit Indique que les conditions doivent être remplies, la relation entre plusieurs conditions est et, ce qui signifie qu'elles sont remplies en même temps
devrait Indique qu'au moins une correspond et que la relation entre plusieurs conditions est ou, ce qui indique qu'au moins une est satisfaite
filtre Les conditions doivent être remplies. Contrairement à must, le filtre est exécuté dans le contexte de filtrage et le score de pertinence n'est pas calculé
ne doit pas Les conditions ne doivent pas être remplies, exécutées dans le contexte de filtrage et le score de pertinence n'est pas calculé

Remarque: must_not est dans le contexte du filtre (exécution du contexte du filtre)

{
    
    
  "query": {
    
    
    "bool" : {
    
    
      "must" : {
    
    
        "term" : {
    
     "status" : 1 }
      },
      "filter": {
    
    
        "term" : {
    
     "type" : "Component" }
      },
      "must_not" : {
    
    
        "range" : {
    
    
          "ctime" : {
    
     "gte" : "2019-12-01", "lte" : "2020-01-01" }
        }
      },
      "should" : [
        {
    
     "term" : {
    
     "tag" : "Kafka" } },
        {
    
     "term" : {
    
     "tag" : "Elasticsearch" } }
      ]
    }
  }
}

Comme indiqué ci-dessus, terme signifie requête de terme, ce qui signifie correspondance exacte, et requête de plage signifie correspondance de plage.

La signification de la requête ci-dessus est que le champ status dans le document doit être 1, le champ type doit être "Component", le champ ctime doit être compris entre 2019-12-01 et 2020-01-01 et le champ tag doit contenir "Kafka" Ou "Elasticsearch".

Requête de recherche en texte intégral

rencontre

La correspondance la plus couramment utilisée est l'index de texte intégral du champ correspondant.

{
    
    
  "match" : {
    
    
        "lauguage" : "Java"
    }
}
{
    
    
    "query": {
    
    
        "match" : {
    
    
            "message" : {
    
    
                "query" : "java python ruby"
            }
        }
    }
}

multi_match

multi_match est similaire à match, mais vous pouvez spécifier plusieurs champs à rechercher.

{
    
    
  "query": {
    
    
    "multi_match" : {
    
    
      "query":    "java python ruby", 
      "fields": [ "subject", "message" ] 
    }
  }
}

match_all

Match_all peut interroger tous les champs d'index et match_all est utilisé par défaut sans conditions de requête.

{
    
    
  "match_all" : {
    
    }
}

match_phrase

match_phrase est un peu similaire à match, mais il y a deux grandes différences:

  1. Le mot pour la segmentation de la requête doit apparaître dans le champ de segmentation correspondant du document
  2. L'ordre des mots doit également être le même
{
    
    
    "query": {
    
    
        "match_phrase" : {
    
    
            "message" : "java python ruby"
        }
    }
}

La position relative peut être ajustée à l'aide du paramètre slop

{
    
    
  "query": {
    
    
      "match_phrase": {
    
    
          "message": {
    
    
              "query": "java python ruby",
              "slop": 2
          }
      }
  }
}

Vous pouvez vous référer à l'exemple de requête suivant, voici les données de test:
slop-tout

pas de pente

Comme le montre la figure ci-dessus, il s'agit du résultat de la requête sans le paramètre slop.

pente 2

Comme le montre la figure ci-dessus, il s'agit du résultat de la requête avec le paramètre slop de 2.

slop3

Comme le montre la figure ci-dessus, il s'agit du résultat de la requête avec le paramètre slop de 3.

Nous pouvons voir que le paramètre slop est d'ajuster le mot slop-1 dans le mot de requête.

match_phrase_prefix

match_phrase_prefix est similaire à match_phrase, mais exécute la correspondance de préfixe

{
    
    
    "query": {
    
    
        "match_phrase_prefix" : {
    
    
            "message" : {
    
    
                "query" : "java python r"
            }
        }
    }
}

Autres requêtes courantes

À la suite de la requête booléenne, de la requête de recherche en texte intégral et du terme associé, de la plage et des autres requêtes que nous avons présentées ci-dessus, nous avons également d'autres requêtes couramment utilisées, présentons-les brièvement ci-dessous.

termes

Plus tôt, nous avons mentionné le terme requête, qui signifie correspondance exacte. Les termes et le terme sont fondamentalement les mêmes, mais les termes permettent de définir plusieurs valeurs. Tant qu'une valeur correspond exactement, la correspondance est réussie.

{
    
    
  "query" : {
    
    
      "terms" : {
    
    
          "component" : ["kafka", "elasticsearch"],
          "boost" : 1.5
      }
  }
}

Comme indiqué ci-dessus, cela signifie que tant que le champ de composant correspond exactement à kafka ou elasticsearch, la correspondance est réussie.

Boost affecte la pertinence du document, supérieur à 1 signifie augmenter la pertinence du document pendant le calcul, et inférieur à 1 signifie réduire la pertinence du document pendant le calcul.

terms_set

La requête terms_set reçoit un tableau, si le champ correspondant dans le document contient au moins la valeur spécifiée dans le tableau de paramètres, il correspond.

Cela semble un peu compliqué, cela n'a pas d'importance, regardons un exemple, créons d'abord un index utilisateur, puis ajoutez 2 documents comme suit.

PUT / user / _doc / 1? Refresh

{
    
    
    "name": "tim",
    "hobby": ["看书", "跑步"],
    "required_matches": 2
}

PUT / user / _doc / 2? Refresh

{
    
    
    "name": "allen",
    "hobby": ["看书", "冥想"],
    "required_matches": 2
}

Nous pouvons maintenant exécuter la requête terms_set.
GET / utilisateur / _search

{
    
    
    "query": {
    
    
        "terms_set": {
    
    
            "hobby.keyword": {
    
    
                "terms": ["看书", "游泳", "冥想"],
                "minimum_should_match_field": "required_matches"
            }
        }
    }
}

Comme indiqué ci-dessus, hobby.keyword est utilisé dans la requête au lieu de hobby, car le mappage n'est pas défini lorsque le mappage utilisateur est ajouté et hobby est automatiquement mappé au type de texte, mais le mappage automatique utilise également le paramètre fields, nous pouvons donc utiliser hobby. mot-clé à rechercher.

Si vous avez peur des problèmes, vous pouvez directement définir le mappage et définir hobby comme type de mot-clé.

La recherche ci-dessus trouvera le document dont le nom est allen. Si nous remplaçons "méditation" par "courant", nous trouverons le document dont le nom est tim.

Il semble plus pénible que le nombre minimum de correspondances soit défini dans le document, au lieu de définir directement la valeur dans la requête. La requête utilise le plus petit champ correspondant du document de référence

existe

{
    
    
    "query": {
    
    
        "exists": {
    
    
            "field": "gid"
        }
    }
}

ids

{
    
    
    "query": {
    
    
        "ids" : {
    
    
            "values" : ["1", "3", "5", "7", "9"]
        }
    }
}

préfixe

La correspondance de préfixe est parfois très utile, par exemple, nous recherchons Lao Wang:

{
    
    
  "query": {
    
    
      "prefix" : {
    
     "name" : "王" }
  }
}

joker

Si vous pensez que la requête de préfixe ne peut pas répondre à vos besoins, vous pouvez également envisager une requête générique.

{
    
    
  "query": {
    
    
      "wildcard": {
    
    
          "name": {
    
    
              "value": "王*五",
              "boost": 1.5
          }
      }
  }
}

joker prend en charge 2 jokers:

  1. ? Signifie correspondre à un personnage
  2. * Match 0 à plusieurs caractères

La valeur de boost peut affecter la pertinence, moins de 1 signifie réduire la pertinence du document, et plus de 1 signifie augmenter la pertinence du document.

Si les caractères génériques ne répondent pas aux exigences, vous pouvez également envisager une requête d'expression régulière de regexp

Cependant, il est fortement recommandé de n'utiliser le préfixe que dans l'environnement en ligne. Si vous souhaitez affecter la pertinence du score, utilisez un caractère générique et ne commencez pas par un caractère générique.

constant_score

Lorsque nous voulons uniquement filtrer, nous pouvons considérer la requête constant_score:

{
    
    
  "query": {
    
    
    "bool": {
    
    
      "must": {
    
    
        "match_all": {
    
    }
      },
      "filter": {
    
    
        "term": {
    
    
          "status": 1
        }
      }
    }
  }
}

Équivalent à:

{
    
    
  "query": {
    
    
    "constant_score": {
    
    
      "filter": {
    
    
        "term": {
    
    
          "status": 1
        }
      }
    }
  }
}

Documentation

Contexte de requête et de filtre

Requête structurée

requête booléenne

rencontre

Je suppose que tu aimes

Origine blog.csdn.net/trayvontang/article/details/107998923
conseillé
Classement