Recherche…


Remarques

Il est facile de voir les type comme une table dans une base de données SQL, où l' index est la base de données SQL. Cependant, ce n’est pas un bon moyen d’aborder le type s.

Tout sur les types

En fait, les types sont littéralement un champ de métadonnées ajouté à chaque document par Elasticsearch: _type . Les exemples ci-dessus ont créé deux types: my_type et my_other_type . Cela signifie que chaque document associé aux types a un champ supplémentaire défini automatiquement comme "_type": "my_type" ; Ceci est indexé avec le document, ce qui en fait un champ de recherche ou de filtrage , mais cela n’a pas d’impact sur le document brut lui-même, votre application n’a donc pas besoin de s’en préoccuper.

Tous les types vivent dans le même index, et donc dans les mêmes fragments collectifs de l'index. Même au niveau du disque, ils vivent dans les mêmes fichiers. La seule séparation fournie par la création d'un second type est une séparation logique. Chaque type, qu'il soit unique ou non, doit exister dans les mappages et tous ces mappages doivent exister dans votre état de cluster. Cela consomme de la mémoire et, si chaque type est mis à jour de manière dynamique, il réduit les performances à mesure que les mappages changent.

En tant que tel, il est recommandé de ne définir qu'un seul type, sauf si vous avez réellement besoin d'autres types. Il est courant de voir des scénarios où plusieurs types sont souhaitables. Par exemple, imaginez que vous avez un index de voiture. Il peut vous être utile de le décomposer en plusieurs types:

  • BMW
  • chevy
  • honda
  • Mazda
  • mercedes
  • nissan
  • rangerover
  • toyota
  • ...

De cette façon, vous pouvez rechercher toutes les voitures ou les limiter par fabricant à la demande. La différence entre ces deux recherches est aussi simple que:

GET /cars/_search

et

GET /cars/bmw/_search

Ce qui n'est pas évident pour les nouveaux utilisateurs d'Elasticsearch, c'est que la seconde forme est une spécialisation de la première forme. Il est littéralement réécrit pour:

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

Il filtre simplement tout document non indexé avec un champ _type dont la valeur était bmw . Comme chaque document est indexé avec son type en tant _type champ _type , cela sert de filtre assez simple. Si une recherche réelle avait été fournie dans l'un ou l'autre exemple, le filtre serait alors ajouté à la recherche complète, le cas échéant.

Ainsi, si les types sont identiques, il est préférable de fournir un seul type (par exemple, le manufacturer dans cet exemple) et de l'ignorer efficacement. Ensuite, dans chaque document, fournissez explicitement un champ appelé make ou quel que soit le nom que vous préférez et filtrez-le manuellement chaque fois que vous souhaitez vous y limiter. Cela réduira la taille de vos mappages à 1/nn est le nombre de types séparés. Il ajoute un autre champ à chaque document, au profit d'une cartographie autrement simplifiée.

Dans Elasticsearch 1.x et 2.x, un tel champ doit être défini comme

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. Le nom est arbitraire.
  2. Le nom est arbitraire et il pourrait correspondre au nom du type si vous le vouliez également.

Dans Elasticsearch 5.x, ce qui précède fonctionnera toujours (il est obsolète), mais le meilleur moyen est d'utiliser:

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. Le nom est arbitraire.
  2. Le nom est arbitraire et il pourrait correspondre au nom du type si vous le vouliez également.

Les types doivent être utilisés avec parcimonie dans vos index, car ils gonflent les mappages d'index, généralement sans grand bénéfice. Vous devez en avoir au moins un, mais rien ne dit que vous devez en avoir plus d’un.

Questions courantes

  • Que se passe-t-il si j'ai deux types (ou plus) qui sont pour la plupart identiques, mais qui ont quelques champs uniques par type?

Au niveau de l'index, il n'y a pas de différence entre un type utilisé avec quelques champs peu utilisés et entre plusieurs types partageant un groupe de champs non fragmentés avec quelques champs non partagés (ce qui signifie que l'autre type n'utilise même pas le champ (s)).

Dit différemment: un champ peu utilisé est rare à travers l'index indépendamment des types . La rareté ne profite pas - ou ne fait vraiment pas mal - l’indice simplement parce qu’il est défini dans un type distinct.

Vous devez simplement combiner ces types et ajouter un champ de type distinct.

  • Pourquoi des types distincts doivent-ils définir des champs exactement de la même manière?

Parce que chaque champ n'est réellement défini qu'une seule fois au niveau Lucene, quel que soit le nombre de types. Le fait que les types existent du tout est une caractéristique d'Elasticsearch et ne constitue qu'une séparation logique.

  • Puis-je définir des types séparés avec le même champ défini différemment?

Non. Si vous parvenez à trouver un moyen de le faire dans ES 2.x ou version ultérieure, vous devez alors ouvrir un rapport de bogue . Comme indiqué dans la question précédente, Lucene les considère tous comme un seul champ, il n'y a donc aucun moyen de faire en sorte que cela fonctionne correctement.

ES 1.x en a fait une exigence implicite, ce qui permettait aux utilisateurs de créer des conditions dans lesquelles les correspondances d'une partition dans un index différaient réellement d'une autre partition du même index. C'était effectivement une condition de course et cela pouvait entraîner des problèmes imprévus.

Exceptions à la règle

  • Les documents parent / enfant nécessitent des types distincts à utiliser dans le même index.
    • Le parent vit dans un type.
    • L'enfant vit dans un type distinct (mais chaque enfant vit dans le même fragment que son parent).
  • Des cas d'utilisation extrêmement complexes où la création de tonnes d'indices est indésirable et l'impact de champs rares est préférable à l'alternative.
    • Par exemple, le plug-in de surveillance Elasticsearch, Marvel (1.x et 2.x) ou X-Pack Monitoring (5.x +) surveille Elasticsearch lui-même pour détecter les modifications dans le cluster, les nœuds, les index, les index spécifiques (le niveau d'index), et même des éclats. Il pourrait créer plus de 5 index chaque jour pour isoler les documents ayant des correspondances uniques ou aller à l'encontre des meilleures pratiques pour réduire la charge du cluster en partageant un index (note: le nombre de mappages définis est le même, mais le nombre d'index créés est réduit de n à 1).
    • Ceci est un scénario avancé, mais vous devez tenir compte des définitions de champs partagés entre les types!

Créer explicitement un index avec un type

L'exemple utilise le protocole HTTP de base, qui se traduit facilement par cURL et d'autres applications HTTP. Ils correspondent également à la syntaxe Sense , qui sera renommée en console dans Kibana 5.0.

Remarque: L'exemple insère <#> pour attirer l'attention sur les pièces. Ceux-ci doivent être supprimés si vous le copiez!

PUT /my_index <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "integer"
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "float"
            }
          }
        }
      }
    }
  },
  "my_other_type": {
    "properties": {
      "field1": {
        "type": "long" <3>
      },
      "field3": { <4>
        "type": "double"
      }
    }
  }
}
  1. Cela crée l' index utilisant le noeud final create index.
  2. Cela crée le type .
  3. Les champs partagés dans le type s dans le même index doivent partager la même définition! ES 1.x n'a pas strictement appliqué ce comportement, mais c'était une exigence implicite. ES 2.x et ci-dessus appliquent strictement ce comportement.
  4. Les champs uniques à travers le type s sont corrects.

Les index (ou index) contiennent des types. Les types sont un mécanisme pratique pour séparer des documents, mais ils nécessitent que vous définissiez - dynamiquement / automatiquement ou explicitement - un mappage pour chaque type que vous utilisez. Si vous définissez 15 types dans un index, vous avez 15 mappages uniques.

Voir les remarques pour plus de détails sur ce concept et pourquoi vous pouvez ou non vouloir utiliser des types.

Création dynamique d'un index avec un type

L'exemple utilise le protocole HTTP de base, qui se traduit facilement par cURL et d'autres applications HTTP. Ils correspondent également à la syntaxe Sense , qui sera renommée en console dans Kibana 5.0.

Remarque: L'exemple insère <#> pour attirer l'attention sur les pièces. Ceux-ci doivent être supprimés si vous le copiez!

DELETE /my_index <1>

PUT /my_index/my_type/abc123 <2>
{
  "field1" : 1234, <3>
  "field2" : 456,
  "object1" : {
    "field1" : 7.8 <4>
  }
}
  1. S'il existe déjà (à cause d'un exemple précédent), supprimez l'index.
  2. my_index un document dans l'index, my_index , avec le type, my_type et l'ID abc123 (peut être numérique, mais c'est toujours une chaîne).
    • Par défaut, la création d'index dynamique est activée en indexant simplement un document. Ceci est idéal pour les environnements de développement, mais ce n'est pas nécessairement bon pour les environnements de production.
  3. Ce champ est un nombre entier, donc la première fois qu'il est vu, il doit être mappé. Elasticsearch prend toujours le type le plus large pour tout type entrant, de sorte qu'il serait mappé comme un long plutôt qu'un integer ou un short (les deux pouvant contenir 1234 et 456 ).
  4. La même chose est vraie pour ce domaine également. Il sera mappé comme un double plutôt que comme un float comme vous le souhaitez.

Cet index et ce type créés dynamiquement correspondent approximativement au mappage défini dans le premier exemple. Cependant, il est essentiel de comprendre comment <3> et <4> affectent les mappages définis automatiquement.

Vous pouvez suivre cela en ajoutant un autre type dynamiquement au même index:

PUT /my_index/my_other_type/abc123 <1>
{
  "field1": 91, <2>
  "field3": 4.567
}
  1. Le type est la seule différence avec le document ci-dessus. L'identifiant est le même et ça va! Il n'a pas de relation avec l'autre abc123 n'est qu'il se trouve dans le même index.
  2. field1 existe déjà dans l'index, il doit donc être du même type que celui défini dans les autres types. Soumettre une valeur qui était une chaîne ou non un entier échouerait (par exemple, "field1": "this is some text" ou "field1": 123.0 ).

Cela créerait dynamiquement les mappages pour my_other_type dans le même index, my_index .

Remarque: Il est toujours plus rapide de définir les mappages au lieu de demander à Elasticsearch de l'exécuter dynamiquement au moment de l'index.

Le résultat final de l'indexation des deux documents serait similaire au premier exemple, mais les types de champs seraient différents et par conséquent légèrement inutiles:

GET /my_index/_mappings <1>
{
  "mappings": {
    "my_type": { <2>
      "properties": {
        "field1": {
          "type": "long"
        },
        "field2": {
          "type": "long" <3>
        },
        "object1": {
          "type": "object",
          "properties": {
            "field1" : {
              "type": "double" <4>
            }
          }
        }
      }
    }
  },
  "my_other_type": { <5>
    "properties": {
      "field1": {
        "type": "long"
      },
      "field3": {
        "type": "double"
      }
    }
  }
}
  1. Cela utilise le point de terminaison _mappings pour obtenir les mappages de l'index que nous avons créé.
  2. Nous avons créé dynamiquement my_type dans la première étape de cet exemple.
  3. field2 est maintenant un long au lieu d'un integer parce que nous ne l'avons pas défini au départ. Cela peut s'avérer être un gaspillage de stockage sur disque.
  4. object1.field1 est maintenant un double pour la même raison que # 3 avec les mêmes ramifications que # 3.
    • Techniquement, un long peut être compressé dans beaucoup de cas. Cependant, un double ne peut pas être compressé car il s'agit d'un nombre à virgule flottante.
  5. Nous avons également créé dynamiquement my_other_type dans la deuxième étape de cet exemple. Sa cartographie se révèle être la même parce que nous utilisions déjà le long et le double .
    • Rappelez-vous que field1 doit correspondre à la définition de my_type (et il le fait).
    • field3 est unique pour ce type, il n'a donc pas cette restriction.


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow