Répertoire d'articles
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:
- contexte de requête
- 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:
- Le mot pour la segmentation de la requête doit apparaître dans le champ de segmentation correspondant du document
- 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:
Comme le montre la figure ci-dessus, il s'agit du résultat de la requête sans le paramètre slop.
Comme le montre la figure ci-dessus, il s'agit du résultat de la requête avec le paramètre slop de 2.
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:
- ? Signifie correspondre à un personnage
- * 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
}
}
}
}
}