Elasticsearch: Supprimer la prise en charge des types ?

Créé le 22 déc. 2015  ·  75Commentaires  ·  Source: elastic/elasticsearch

La possibilité d'avoir plusieurs types sur le même index pose problème :

  • les API de mappages doivent maintenir un mappage par type, mais ces mappages ne peuvent pas être indépendants et les maintenir synchronisés est compliqué (voir par exemple les discussions sur # 15539)
  • cela donne l'impression que le système peut facilement traiter des documents qui ont des mappages très différents dans le même index, ce qui n'est pas vrai. C'est pourquoi dans la version 2.0, nous avons ajouté plus de restrictions sur les mappages entre les types. De plus, les types encouragent la parcimonie et les champs clairsemés ralentissent Lucene lorsqu'il existe une implémentation spéciale pour le cas clairsemé (par exemple, les valeurs doc) ou utilisent énormément de mémoire et d'espace disque malgré le fait que peu de documents ont une valeur (par exemple ., car une quantité fixe de mémoire est utilisée pour chaque document, qu'ils aient ou non une valeur pour ce champ).

La migration des utilisateurs existants va certainement être compliquée, mais cela rendrait également le système plus honnête vis-à-vis des nouveaux utilisateurs sur le fait que nous ne pouvons pas effectuer efficacement la multilocation au niveau de l'index. De plus, je soupçonne que les restrictions que nous avons ajoutées dans la version 2.0 (par exemple, deux champs portant le même nom dans différents types) ont déjà fait migrer de nombreux utilisateurs vers un seul index par type de données au lieu de les plier en différents types du même index .

Voir aussi https://www.elastic.co/blog/index-vs-type.

:SearcMapping Meta

Commentaire le plus utile

Salut,

S'il vous plaît, pourrait-il être documenté dans la documentation ES que le plan à long terme est de s'éloigner de plusieurs types par index, afin que les personnes qui démarrent de nouveaux projets sachent maintenant les éviter, et pour les personnes qui ont des projets qui utilisent déjà plusieurs mappages, pour commencer traverser les sept étapes de la perte le plus tôt possible.

Je ne suis tombé sur ce problème que par hasard lors de la lecture des index par rapport aux types via google.

Évidemment, excusez-moi à l'avance si cela a déjà été documenté et que je l'ai manqué.

à votre santé
Dan

Tous les 75 commentaires

Il semble que la suppression de la prise en charge des types serait bloquée sur https://github.com/elastic/elasticsearch/issues/11432.

Ce serait bien si cela accélérait les relations parent-enfant entre les index, cela éliminerait une grande partie de la rareté susmentionnée.

Qu'en est-il de séparer les mappages des types ? Faire des mappages une fonctionnalité au niveau de l'index et des types comme une partie de l'identifiant ? Cela les rendrait-il suffisamment légers pour ne pas gêner?

@zygfryd en effet

@ nik9000 C'est aussi une option. Au moins, cela indiquerait clairement qu'il existe un seul mappage par index et nous pourrions simplifier les éléments internes. Avec cette option, je suppose que les types resteraient uniquement des filtres de première classe (par exemple, nous pourrions effectuer un tri d'index sur _type afin que le filtrage soit plus rapide) ?

les types resteraient uniquement des filtres de première classe

Je serais d'accord avec ça.

Je pense que séparer les mappages des types est une bonne idée. À mon avis, la suppression des types est trop radicale.

Dans notre cas d'utilisation (gestion des journaux), nous avons plus de 80 types de journaux et nous utilisons un index (quotidien, hebdomadaire ou mensuel) par projet/locataire pour pouvoir gérer la charge.
Nous avons des mappages différents pour chaque type de journaux, mais les mappages sont identiques pour tous les index.

De plus, les types encouragent la parcimonie et les champs clairsemés ralentissent Lucene lorsqu'il existe une implémentation spéciale pour le cas clairsemé (par exemple, les valeurs doc) ou utilisent énormément de mémoire et d'espace disque malgré le fait que peu de documents ont une valeur (par exemple ., car une quantité fixe de mémoire est utilisée pour chaque document, qu'ils aient ou non une valeur pour ce champ).

Si je vous ai bien lu, on devrait plutôt utiliser un index par type de log ?
Dans notre cas d'utilisation, nous avons des besoins différents pour chaque projet/locataire. Certains projets peuvent enregistrer jusqu'à 5 000 journaux/s tandis que d'autres projets n'enregistrent que 10 journaux/s.
Nous devons donc pouvoir configurer les répliques/shards et la fréquence de création d'index (quotidienne, hebdomadaire, mensuelle...) par projet/locataire.

Pourriez-vous s'il vous plaît expliquer un peu plus votre proposition avec ce cas d'utilisation et avec les types supprimés ?

Faire des mappages une fonctionnalité au niveau de l'index

:+1:

Si je vous ai bien lu, on devrait plutôt utiliser un index par type de log ?

Oui. Les types sont pièges : à première vue, ils semblent être un moyen efficace d'avoir plusieurs locataires dans un seul index, mais en pratique, cela rend généralement les choses _pires_ que d'avoir plusieurs index en raison du fait que Lucene préfère les données denses aux données clairsemées, en particulier pour normes et valeurs doc.

Si certains locataires ont des taux d'indexation inférieurs, ils obtiendront moins de partitions et/ou des délais plus longs (par exemple, des index hebdomadaires au lieu de quotidiens).

J'ai d'abord pensé que séparer les types des mappages serait un bon compromis, mais les types ont un autre problème en ce sens qu'ils nous obligent à replier le type dans l'uid, ce qui rend généralement le _uid moins efficace (indexation plus lente et obtention plus lente) si nous préfixons le type (comme aujourd'hui) ou plus gourmand en espace si nous ajoutons le type. Je pense donc que nous devrions penser à nous débarrasser complètement des types. Par exemple, nous pourrions peut-être envisager d'appliquer un seul type par index dans la version X, les API fonctionnant toujours avec index/type ou simplement index , puis de supprimer entièrement les types dans la version X+1 ?

Je pense que nous devrions déprécier le type dans la version 5.0 et commencer à évoluer vers des mappages au niveau de l'index, uuid par index et non par type, etc. Si quelqu'un a vraiment besoin du type dans l'UUID, il peut toujours le faire, je suppose. Les types peuvent être construits sur es sans support natif, il n'y a rien aujourd'hui qui vous empêche de le faire. Cela complique plutôt les choses en interne sans réel avantage pour l'extérieur, à l'exception du support API de premier niveau que quelqu'un pourrait trouver utile, mais qui n'est que du sucre syntaxique avec un prix potentiellement élevé à payer. Je suis également +1 pour supprimer entièrement cela dans la version 6.0 et guider les gens sur la façon de le faire correctement.

La principale préoccupation que j'ai pour l'instant est le support de la fonctionnalité parent/enfant.
Aujourd'hui, nous avons besoin d'avoir des données colocalisées dans le même fragment pour le parent et les enfants afin d'effectuer des jointures en mémoire.

La suppression des types permettra uniquement de faire parent/enfant en utilisant le même "type" de document.

Pas super terrible car en fin de compte, c'est ce qui se passe dans les coulisses.

Donc si nous avions :

PUT index/company/1
{
  "name": "elastic"
}
PUT index/employee/11?parent=1
{
  "first_name": "david"
}

Nous devrons essentiellement réécrire ceci comme par exemple:

PUT index/1
{
  "company": {
    "name": "elastic"
  }
}
PUT index/11?parent=1
{
  "employee": {
    "name": "david"
  }
}

Cela signifie que le parent/enfant pourra faire l'auto référencement comme proposé ici dans #11432.
Donc, dès que nous avons le support pour # 11432, je suis totalement +1 pour supprimer les types.

BTW, peut-être devrions-nous déjà commencer à éduquer les gens à n'utiliser qu'un seul type par index et à utiliser des structures de données similaires à ce que j'ai proposé dans mon exemple ?

Qu'en est-il du plan suivant :

  • exiger que les index 5.0+ aient au plus un type (ce qui signifie que parent/enfant ne fonctionne pas)
  • ajouter des API sans paramètre de type, par exemple. POST index/ pour indexer avec un identifiant généré automatiquement ou PUT index/id pour indexer avec un identifiant explicite, supprimer l'exigence d'avoir le nom du type comme clé de niveau supérieur dans les mappages, etc. (tout cela n'a pas besoin d'être fait en 5.0, cela pourrait venir en 5.x)
  • supprimer les types des API dans 6.0+
  • travailler séparément sur une autre façon d'exposer les jointures de manière raisonnable, en remplacement du parent/enfant (en supposant que nous voulions un remplacement)

Si nous ne sommes pas prêts à supprimer parent/enfant pour le moment, un compromis auquel je pourrais consentir serait d'avoir un paramètre qui permet aux index d'avoir plusieurs types afin que parent/enfant puisse être utilisé, mais ces index ne pourraient pas être mis à niveau vers 6.0.

Pour mémoire, nous avons des preuves que la suppression des types pourrait améliorer considérablement la vitesse d'indexation, car nous n'aurions pas à replier le nom du type dans l'uid : https://github.com/elastic/elasticsearch/issues/18154#issuecomment -237851085

Les pensées?

@jpountz Je pense que nous devrions le faire, mais il semble que votre proposition soit passée inaperçue compte tenu du manque de réaction (positive ou négative). Pouvons-nous avoir d'autres idées à ce sujet?

/cc @s1monw @clintongormley

@rjernst je le regarde pendant que vous tapez :)

Nous en avons discuté dans Fix it Friday.

Où nous voulons arriver :

Nous souhaitons supprimer le concept de types d'Elasticsearch, tout en prenant en charge parent/enfant.

  • Les mappages de champs seront au niveau supérieur, au lieu de sous les noms de type
  • Le _uid ne comprendra que le _id , pas type#id .
  • Création d'un document avec ID : PUT index/_doc/id
  • Création d'un document avec ID généré automatiquement : POST index/_doc

Il est très important pour moi que nous ne laissions pas les utilisateurs de côté - nous devons leur offrir un chemin de mise à niveau et de transition en douceur.

Cheminement proposé :

En 5.0 :

  • [ ] Dans les nouveaux index, imposez que les champs portant le même nom dans différents types doivent avoir des mappages identiques.
  • [x] POST index ne devrait plus créer d'index. #20001
  • [x] Vérifiez d'autres points de terminaison REST pour des conflits similaires. #20055

Dans 5.x :

  • [x] Ajout de la prise en charge de la définition enabled:false dans le champ _type , qui exclura le type de l'UID et utilisera un nom de type fixe pour (par exemple) mapper les requêtes/réponses. Ces index ne prendront pas en charge parent/enfant. #24317
  • [x] Ajout de la prise en charge de PUT index/_doc/id , POST index/_doc et PUT|POST index/_mapping
  • [x] Ajout d'un nouveau mécanisme pour spécifier et prendre en charge parent/enfant.

En 6.0 :

  • [x] Empêche la création de nouveaux index avec plus d'un type.

En 6.7 :

  • [x] Pour les API dont la structure de requête/réponse change avec la suppression des types (créer un index, obtenir un mappage, etc.), ajoutez un paramètre de chaîne de requête (par exemple, include_type_name ) qui indique si les requêtes/réponses doivent inclure un type Nom. Ce paramètre est par défaut à true . Émettre un avertissement d'obsolescence pour toutes les requêtes qui ne définissent pas include_type_name sur false

Dans 7.0 :

  • [x] Supprimer la prise en charge de l'ancien parent/enfant (#29224)
  • [x] Pour les requêtes dont la structure ne change pas avec la suppression des types, assurez-vous d'accepter les versions avec et sans type de l'API. Émettez un avertissement d'obsolescence pour les demandes qui spécifient des types.
  • [x] Par défaut include_type_name à false . Émettez un avertissement d'obsolescence pour toutes les requêtes qui include_type_name .
  • [x] Dépréciation des références aux types dans le client Java de repos de haut niveau

En 8.0

  • [ ] type ne peut plus être spécifié dans les requêtes
  • [ ] le paramètre include_type_name est supprimé

Dans la version 6.0, tous les types existants des index 5.x auront des mappages identiques. Nous aurons toujours des index avec l'ancienne implémentation parent/enfant. Si nous pouvons migrer les paramètres parent/enfant existants vers les nouveaux paramètres, nous pourrions déplacer le problème des "champs de retour au niveau supérieur" dans la version 6.0.

Alternativement, nous pourrions renvoyer les champs au niveau supérieur dans la version 6.0, et toujours afficher les types (pour les anciens index avec les types activés ou avec l'ancien parent-enfant) dans une section distincte du mappage GET.

MISE À JOUR POUR REFLÉTER LES CHANGEMENTS DANS https://github.com/elastic/elasticsearch/issues/15613#issuecomment -303727982

MISE À JOUR POUR REFLÉTER LES CHANGEMENTS DANS https://github.com/elastic/elasticsearch/issues/15613#issuecomment -382427200

MISE À JOUR POUR REFLÉTER LES CHANGEMENTS DANS https://github.com/elastic/elasticsearch/issues/15613#issuecomment -438084242

MISE À JOUR POUR REFLÉTER LES MODIFICATIONS DISCUTÉES DANS https://github.com/elastic/elasticsearch/issues/35190

Recherchez d'autres points de terminaison REST pour des conflits similaires.

Je pense que le seul autre point de terminaison que nous devons vérifier est PUT/POST {index}/_mapping , qui est gratuit aujourd'hui. Est-ce que j'en manque un autre ?

indices.exists_type ( HEAD {index}/{type} ) se heurte à un exists ( HEAD {index}/{id} ) sans type

Peut-être que le formulaire existant devrait être abandonné au profit de HEAD {index}/_mapping/{type}

Je pense que c'est tout

Dans les nouveaux index, imposez que les champs portant le même nom dans différents types doivent avoir des mappages identiques.

Ayant commencé à travailler dessus, c'est plus difficile que je ne le pensais au départ. Cependant, je pense que cela pourrait ne pas être nécessaire : puisque nous aurons de toute façon besoin d'au plus un type dans la version 6.0+, nous n'aurons pas à fusionner les mappages entre les types dans la version 7.0, donc cette étape n'est pas requise pour la suppression du type ?

@clintongormley J'aime le plan proposé ! _Si_ nous pouvons trouver un moyen de prendre en charge le nouveau format parent/enfant dans 5.x avec l'activation définie sur false sur _type, cela signifierait une migration plus simple sur la route. Nous pourrions commencer à faire pression pour définir ce paramètre pour les nouveaux utilisateurs.

@clintongormley je crois ceci:

Dans les nouveaux index, imposez que les champs portant le même nom dans différents types doivent avoir des mappages identiques.

Est résolu (à partir des cases à cocher 5.0):

PUT /i?pretty
{
  "mappings": {
    "typea": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "standard"
        }
      }
    },
    "typeb": {
      "properties": {
        "title": {
          "type": "text",
          "analyzer": "english"
        }
      }
    }
  }
}

{
  "error" : {
    "root_cause" : [
      {
        "type" : "mapper_parsing_exception",
        "reason" : "Failed to parse mapping [typea]: Mapper for [title] conflicts with existing mapping in other types:\n[mapper [title] has different [analyzer], mapper [title] is used by multiple types. Set update_all_types to true to update [search_analyzer] across all types., mapper [title] is used by multiple types. Set update_all_types to true to update [search_quote_analyzer] across all types.]"
      }
    ],
    "type" : "mapper_parsing_exception",
    "reason" : "Failed to parse mapping [typea]: Mapper for [title] conflicts with existing mapping in other types:\n[mapper [title] has different [analyzer], mapper [title] is used by multiple types. Set update_all_types to true to update [search_analyzer] across all types., mapper [title] is used by multiple types. Set update_all_types to true to update [search_quote_analyzer] across all types.]",
    "caused_by" : {
      "type" : "illegal_argument_exception",
      "reason" : "Mapper for [title] conflicts with existing mapping in other types:\n[mapper [title] has different [analyzer], mapper [title] is used by multiple types. Set update_all_types to true to update [search_analyzer] across all types., mapper [title] is used by multiple types. Set update_all_types to true to update [search_quote_analyzer] across all types.]"
    }
  },
  "status" : 400
}

Donc je _pense_ que cela ne bloque plus pour 5.0, est-ce exact ? (Je ne voulais pas cocher la case s'il manquait autre chose)

En tant qu'utilisateur d'Elasticsearch et quelqu'un qui a passé les derniers mois à travailler sur l'implémentation d'un client de mappage de type, cela me semble bien. D'après ce que je peux dire de la conversation jusqu'à présent : les types ne disparaissent pas _vraiment_, ils sont simplement déplacés vers le niveau de l'index, de sorte que l'index détermine la forme de son type de document, n'est-ce pas ?

D'après ce que je peux dire de la conversation jusqu'à présent : les types ne disparaissent pas vraiment, ils sont simplement déplacés vers le niveau de l'index, de sorte que l'index détermine la forme de son type de document, n'est-ce pas ?

C'est à peu près correct, une fois que nous aurons finalement ajouté la prise en charge de _type: {enabled: false} (et qu'un utilisateur l'utilisera), ce sera un type par index. La seule difficulté sera parent/enfant sur laquelle @martijnvg a travaillé dans https://github.com/elastic/elasticsearch/issues/20257

Je pense donc que cela ne bloque plus pour 5.0, est-ce exact ? (Je ne voulais pas cocher la case s'il manquait autre chose)

Pas assez. Il existe aujourd'hui certaines propriétés qui peuvent différer, par exemple :

PUT t
{
  "mappings": {
    "one": {
      "properties": {
        "text": {
          "type": "text",
          "copy_to": "foo"
        }
      }
    },
    "two": {
      "properties": {
        "text": {
          "type": "text",
          "copy_to": "bar"
        }
      }
    }
  }
}

Ayant commencé à travailler dessus, c'est plus difficile que je ne le pensais au départ. Cependant, je pense que cela pourrait ne pas être nécessaire : puisque nous aurons de toute façon besoin d'au plus un type dans la version 6.0+, nous n'aurons pas à fusionner les mappages entre les types dans la version 7.0, donc cette étape n'est pas requise pour la suppression du type ?

@jpountz a du sens pour moi. OK, je vais supprimer cette tâche et supprimer l'étiquette de blocage.

J'aime ce changement en général, ma seule préoccupation est le fait que les apis de création d'index et de document d'index seront sur le même point de terminaison de repos avec seulement une méthode différente. Je crains que cela ne prête à confusion et soit source d'erreurs pour les utilisateurs.

Comme indiqué ci-dessus, l'index de création ne sera accessible qu'avec PUT index et l'indexation d'un document avec un identifiant généré automatiquement sera POST index . Cela me semble étrange car nous affectons différentes ressources uniquement en fonction de la méthode utilisée (ajout d'un index au cluster vs ajout d'un document à l'index). Nous pourrions à la place avoir le point de terminaison id généré automatiquement comme quelque chose comme POST index/_auto_id . Cela ne devrait pas entrer en conflit avec les identifiants réels, car nous avons déjà une convention de réservation de index/_X pour les points de terminaison (par exemple, index/_mapping ).

Salut,

S'il vous plaît, pourrait-il être documenté dans la documentation ES que le plan à long terme est de s'éloigner de plusieurs types par index, afin que les personnes qui démarrent de nouveaux projets sachent maintenant les éviter, et pour les personnes qui ont des projets qui utilisent déjà plusieurs mappages, pour commencer traverser les sept étapes de la perte le plus tôt possible.

Je ne suis tombé sur ce problème que par hasard lors de la lecture des index par rapport aux types via google.

Évidemment, excusez-moi à l'avance si cela a déjà été documenté et que je l'ai manqué.

à votre santé
Dan

Salut tout le monde,

J'ai déjà posté un commentaire lié au parent/enfant sans type #20257
Maintenant, je voudrais publier une sorte de résumé sur les avantages et les inconvénients des types. La raison en est que plus je pense à la perspective de supprimer des types, plus je sens que je manquerais vraiment ce que cela m'achèterait : considérer le magasin de données dans ES comme UNE entité (ou en quelque sorte).

Avantages:

  • Les types me permettent d'utiliser un index comme une sorte de base de données, chaque "table" étant d'un type différent. Cela peut être considéré comme une sorte de cas limite, mais beaucoup de gens l'utilisent de cette façon et je voudrais dire que c'est une fonctionnalité vraiment intéressante ! Au cours de l'année, j'ai été impliqué dans plusieurs projets tirant parti de l'ES où l'ES est devenu la seule source de données. Dans tous ces projets, ES est la base de données. Il n'y a pas de base de données SQL externe et chaque élément de données est stocké dans un index contenant différents types. Ce qui m'amène au point suivant
  • En termes d'opérations, afin de sauvegarder toutes les données réparties sur plusieurs types, j'ai simplement besoin de prendre un instantané d'un index. Quand quelque chose ne va pas, je restaure simplement UN instantané et je suis de retour dans les affaires. Pour moi, cette fonctionnalité unique est très importante car les données stockées dans ES sont liées. Ce n'est pas un tas d'index mais plutôt un groupe de choses liées. Et Types m'achète ça.

  • On utilise parfois Alias ​​pour effectuer des opérations sur plusieurs types. Par exemple, il peut s'agir de mettre à niveau toutes nos données et de passer aux données mises à niveau en mettant simplement à jour l'alias. Je sais que les alias peuvent déjà pointer vers plusieurs indices, mais encore une fois, lorsque j'utilise ES, les notions de types me permettent de considérer toutes ces données interdépendantes comme une seule base de données (ahem ...) .

Les inconvénients:

  • Plusieurs problèmes principalement (uniquement ?) liés aux mappages, aux incohérences, etc.

Ne vous méprenez pas, je suis d'accord que les types peuvent être déroutants jusqu'à ce que vous compreniez leurs défauts. Une fois que vous en êtes conscient, cela devient presque une évidence.

Pour conclure, nous convenons tous que les types ont des problèmes. Une façon de se débarrasser de ces problèmes est de se débarrasser des types. Serait-il possible de "corriger" ces problèmes et de conserver les types ? Par exemple, serait-il possible de préfixer tous les champs avec les types auxquels ils appartiennent au niveau lucene. Pour moi, cela résoudrait les problèmes de cartographie. WDYT ?

Désolé pour le long post...
Tous mes vœux,

Stéphane

@stephane-bastian

Les types me permettent d'utiliser un index comme une sorte de base de données, chaque "table" étant d'un type différent. Cela peut être considéré comme une sorte de cas limite, mais beaucoup de gens l'utilisent de cette façon et je voudrais dire que c'est une fonctionnalité vraiment intéressante !

C'est une idée fausse commune. Les types ne sont pas des tableaux. Les structures de données sous-jacentes sont les mêmes pour l'index entier, et non par type. Cela signifie que l'utilisation de plusieurs types provoque des lacunes (c'est-à-dire une rareté) dans la structure des données chaque fois que des documents consécutifs ont des champs différents. Lucene gère mieux les données rares, mais cela ne résoudra jamais complètement ce problème.

En termes d'opérations, afin de sauvegarder toutes les données réparties sur plusieurs types, j'ai simplement besoin de prendre un instantané d'un index. Quand quelque chose ne va pas, je restaure simplement UN instantané et je suis de retour dans les affaires.

Vous pouvez créer un instantané de plusieurs index dans un instantané.

On utilise parfois Alias ​​pour effectuer des opérations sur plusieurs types. Par exemple, il peut s'agir de mettre à niveau toutes nos données et de passer aux données mises à niveau en mettant simplement à jour l'alias. Je sais que les alias peuvent déjà pointer vers plusieurs indices, mais encore une fois, lorsque j'utilise ES, les notions de types me permettent de considérer toutes ces données interdépendantes comme une seule base de données (ahem ...) .

Comme vous le dites, vos alias peuvent être utilisés avec plusieurs index. Il n'y a rien d'inhérent aux types qui améliore cela, c'est seulement un filtre supplémentaire ajouté à chaque requête (c'est-à-dire un filtre de terme sur le type essentiellement).

Les inconvénients:
Plusieurs problèmes principalement (uniquement ?) liés aux mappages, aux incohérences, etc.

C'est une simplification radicale. Les types ont causé des problèmes aux utilisateurs pendant très longtemps. Nous avons apporté des améliorations pour corriger les incohérences (par exemple # 8870), et avons discuté des types vraiment donnés aux utilisateurs depuis lors. Les problèmes restants avec les types sont bien présentés par @jpountz dans la description originale du problème ici, ainsi que dans le billet de blog lié.

Par exemple, serait-il possible de préfixer tous les champs avec les types auxquels ils appartiennent au niveau lucene.

Nous avons discuté de cette idée il y a longtemps (à peu près au même moment que # 8870). Il ne résout pas la complexité du code des types et supprime l'un des rares avantages des types (lexique partagé pour des champs similaires).

La clé de tout cela est que les types ne sont pas réellement spéciaux. Il s'agit essentiellement d'un champ supplémentaire, avec un élément du chemin de l'URL traduit en un filtre de requête supplémentaire. C'est simple pour un utilisateur de le faire lui-même s'il le veut vraiment, sans faire tomber les nouveaux utilisateurs dans le piège de "les types sont comme des tables".

Historiquement, les types étaient utiles pour séparer des documents avec une structure différente dans les index. Cependant, dans les versions récentes, cela ne tient pratiquement plus - différents types de documents ne peuvent pas partager le même nom de champ si leurs mappages ne correspondent pas.

De plus, les seules unités gérables dans Elasticsearch sont les documents et les index. Vous pouvez les ajouter et les supprimer. Vous ne pouvez pas gérer les types. En tant que tel, la recommandation habituelle que je donne est de maintenir un index par type - car généralement, lorsque plusieurs types sont impliqués, leurs tailles et leurs SLA sont différents, et donc différentes configurations pour la réplication, la rétention, etc. sont de toute façon nécessaires. Si ce n'est pas maintenant, alors dans le futur.

Avec Elasticsearch qui passe lentement au partitionnement au niveau de l'index et même au niveau du cluster (avec la recherche inter-cluster), et avec des tailles d'index qui ne font que croître dans les systèmes du monde réel - je pense que les chances que les types soient réellement utiles n'importe où sont désormais proches de zéro, et les différents types de documents sont mieux séparés au niveau de l'index.

À ce stade, les types IMO ne sont qu'un bruit inutile pour la majorité des systèmes. Nous pouvons certainement vivre sans eux, taper moins (jeu de mots) et gérer différents types de données en utilisant des index séparés. Cela évitera également divers écueils courants (par exemple, un grand nombre de champs dans la cartographie).

La seule fonctionnalité affectée sera parent/enfant, et je suis sûr qu'il pourrait y avoir une solution simple (j'irais probablement avec un type "invisible" pour les parents et les enfants).

Donc je suis partant pour ça, j'espère arriver à la v6 !

Il y a de nombreuses années, j'ai créé un problème demandant l'inclusion de métadonnées personnalisées au niveau de l'index. La solution de contournement proposée consistait à utiliser un type personnalisé dans le même index avec un seul document : https://github.com/elastic/elasticsearch/issues/1649

J'ai toujours trouvé que plusieurs types dans le même index étaient kludgy (comme le souligne ce problème), donc je n'ai jamais implémenté la solution suggérée, mais j'ai utilisé des alias (avait l'avantage supplémentaire d'être visible dans des interfaces utilisateur telles que head). Ce serait formidable d'avoir des métadonnées personnalisées au niveau de l'index, d'autant plus que la solution de contournement suggérée ne sera plus prise en charge. Veuillez m'excuser si une telle fonctionnalité a été créée depuis le numéro d'origine.

Ce serait formidable d'avoir des métadonnées personnalisées au niveau de l'index,

@brusic Je suppose que le champ méta de mappage couvrira cela, car les mappages seront désormais une chose au niveau de l'index. Est-ce correct?

@bleskes Si le champ méta de mappage est promu à un paramètre de niveau d'index, ce serait parfait.

Si le champ méta de mappage est promu à un paramètre de niveau d'index, ce serait parfait

@brusic Puisque _meta fait partie des mappages, et non d'un document, il est déjà par index.

Devrait vraiment le mentionner dans les docs ou ailleurs. J'ai dû chercher sur Google pendant des heures pour comprendre ce dilemme index-type et ce n'est qu'en tombant accidentellement sur ce ticket que tout a finalement été clair.

Ajoutez la prise en charge du paramètre enabled:false au champ _type, qui exclura le type de l'UID et utilisera un nom de type fixe pour (par exemple) les requêtes/réponses de mappage.

c'est quoi ce nom fixe ? Ou plutôt quelle est la recommandation pour un nom de type par défaut pour 5.4 et plus si vous voulez déjà agir comme si les types n'existaient pas ? default ou _default_ peut-être ? ou chaîne vide?

Salut,
pour le moment, nous utilisons des indices pour séparer les locataires.
Nous avons donc un index par locataire et plusieurs types dans un index.

Nous rencontrons trois problèmes lors du passage à un type par index :

Cohérence sauvegarde/instantané :
Si je comprends bien, faire un instantané d'un index crée une copie cohérente de cet index.
Faire un instantané de plusieurs index signifie que ces index sont à un état de transaction différent.
Ainsi, la restauration de l'ensemble d'index entraîne une inadéquation des données (l'index sauvegardé en premier n'a peut-être pas de données liées par un autre type)

  • comment créer un instantané cohérent sur plusieurs index
  • comment réduire la complexité des instantanés ; besoin d'instantané 30 indices au lieu d'un pour le moment.

Densité de partitions/nombre d'index et de partitions :
Nous avons env. 30 types par index. Avoir 300 locataires exécutés sur un cluster signifie au moins 300x30=9000 index sur le cluster lorsque vous n'utilisez pas de types.
Pour le moment, nous avons env. 900 fragments ; à l'avenir, nous ne pourrions pas descendre en dessous de 9 000 fragments !
Cela se traduirait par 10 à 15 fois plus de fragments exécutés sur le même cluster.

Bien sûr, il serait possible de fusionner tous les locataires en un seul index, mais cela nous conduirait à d'autres gros inconvénients :

  • impossible d'exécuter différentes versions de mappage par locataire
  • impossible de prendre un instantané et de restaurer une granularité de locataire unique
  • impossible d'exécuter différents intervalles de sauvegarde/stratégie/temps de rétention par locataire
  • impossible de déplacer un locataire vers un autre cluster en déplaçant simplement l'index

@lefce , vous pouvez continuer à stocker tous les documents d'un seul locataire dans un seul index. La seule différence est qu'il n'y aura qu'un seul mappage, vous devrez donc ajouter votre propre champ type au lieu d'utiliser le champ de métadonnées _type .

Tous les mappages qui ont des champs du même nom partagent déjà ces champs avec d'autres mappages. Donc, tout ce que nous faisons vraiment, c'est supprimer la fiction selon laquelle il existe plusieurs "tables" indépendantes dans un index.

@clintongormley cela semble être une bonne solution. Nous n'avons donc "qu'à" fusionner les mappages et utiliser notre propre champ de type. Merci pour la réponse rapide!

Je viens d'avoir une réunion avec @jpountz et @s1monw à propos de la migration des URL sans type, qui s'avère compliquée en raison de la nécessité de prendre en charge les index multitypes 5.x en même temps que les index monotypes 6.x.

Nouveau plan de migration pour les URL sans type :

En 6.0

(peut contenir des indices 5.x, avec plusieurs types)

  • type est toujours un paramètre obligatoire dans les URL existantes - les URL ne changent pas du tout
  • Les index 6.x peuvent utiliser le nom type leur choix, mais il ne peut y avoir qu'un seul type dans un index

En 7.0

(tous les indices ont un seul type)

  • type devient un paramètre facultatif dans les URL et est complètement ignoré.
  • pour GET|PUT _mapping nous ajoutons un paramètre de chaîne de requête (par exemple include_type_name ) qui indique si le corps doit inclure une couche pour le nom du type. c'est par défaut true . Les index 7.x qui n'ont pas de type explicite utiliseront le nom de type factice _doc

En 8.0

(tous les index ont un seul type et l'index n'inclut pas les informations de type)

  • type ne peut plus être spécifié dans les URL
  • le paramètre include_type_name est maintenant par défaut à false

En 9.0

  • supprimer le paramètre include_type_name

Mise à jour de la feuille de route dans https://github.com/elastic/elasticsearch/issues/15613#issuecomment -239435920 pour refléter ce qui précède

Nous avons une large base d'utilisateurs formés pour utiliser le champ méta "_type" pour rechercher/naviguer dans nos index multi-types. Pourrons-nous indexer les documents contenant le champ "_type" dans le cadre de leurs attributs de corps ? Il s'agit de rendre le passage aux index sans type aussi fluide que possible.

@haizaar vous pouvez avoir n'importe quel champ que vous voulez et traiter comme un champ de catégorie (ce qu'est le _type actuel, si vous n'en abusez pas). Notez cependant qu'à l'avenir, nous n'autoriserons probablement pas les champs utilisateur commençant par _ pour éviter les collisions avec les méta-champs internes - il n'est donc peut-être pas judicieux de conserver le _type Nom.

Bonne journée tout le monde.

Énorme fil, et peut-être que j'ai raté quelque chose en lisant ceci.

En ce moment, j'utilise la requête has_parent où je recherche des documents de type enfant avec des critères de filtre par champs de type parent. Et avec les prochaines versions d'ES, je dois déplacer ces deux types pour séparer les index.
Cela signifie que je ne peux pas utiliser la requête has_parent à l'avenir et que je ne peux pas modifier facilement la structure de données pour réécrire la requête.
Corrigez-moi si je me trompe, dans ce cas, j'ai besoin d'utiliser un type personnalisé à l'intérieur de l'index ou d'utiliser des objets imbriqués ?

@amelnikoff
Parent-Child passe à un nouveau modèle sans _type_, en utilisant un champ _join .
Voir:

@tvernum
Si je comprends bien, ce sera une relation entre des documents du même type.
Mais j'ai deux types.

Je viens de réaliser que je dois combiner deux types de documents en un seul et que je dois séparer leurs propriétés à l'intérieur de ce type, puis je peux utiliser le champ de jointure.

J'ai une question rapide sur la préparation du passage de 5.x à 6.x, avec la suggestion d'utiliser l'API de repos en masse. Actuellement, la documentation suggère que le _type est toujours nécessaire avec le nom de l'index lors du téléchargement. Dois-je maintenant le laisser vide ? ou peut-être utiliser le nom de l'index pour être sûr ? Jusqu'à présent, j'utilisais le _type comme forme de classification, mais je peux facilement le déplacer ailleurs.

Merci

@wtarr Dans 6.0, les index ont toujours des types, mais vous ne pouvez avoir qu'un seul type par index. Nous ne supprimerons officiellement le nom du type que dans la version 7.0.

Vous pouvez donc simplement utiliser le type doc ou autre.

Je me demandais aujourd'hui en voyant ce PR #27869 s'il fallait aussi penser à supprimer l'API PUT mapping ?
Je veux dire qu'à la fin de la journée, nous n'aurons qu'un seul "type" par index, en faisant quelque chose comme :

PUT index
{
  "settings": {}
}
PUT index/_mapping
{
  "doc": { }
}

Pourrait être remplacé de toute façon par quelque chose comme:

PUT index
{
  "settings": {},
  "mappings": {
    "doc": { }
  }
}

@jpountz WDYT ?

Puisqu'il n'y a qu'UN seul mappage par index, l'élément "mappings" ne devrait-il pas être renommé en "mappage" à un moment donné ?

Puisqu'il n'y a qu'UN seul mappage par index, l'élément "mappings" ne devrait-il pas être renommé en "mappage" à un moment donné ?

La partie plurielle concerne plusieurs champs, pas plusieurs types.

Je me demandais aujourd'hui en voyant ce PR #27869 s'il fallait aussi penser à supprimer l'API PUT mapping ?

+1

Fwiw, une API de mise à jour des paramètres d'indices existe également, même si chaque index n'a jamais eu qu'un seul ensemble de paramètres : https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html

@dadoonet Je pense que l'API Update Mapping serait toujours utile même avec un seul type puisque vous pouvez l'utiliser pour ajouter de nouveaux champs aux mappages après la création de l'index.

Je pense que l'API Update Mapping serait toujours utile même avec un seul type puisque vous pouvez l'utiliser pour ajouter de nouveaux champs aux mappages après la création de l'index.

@colings86 Ha ! Très vrai. J'ai oublié ça o_O.
Vous vous demandez si cela peut être pris en charge par les paramètres de mise à jour ?

Vous voulez dire mettre à jour les mappages via l'API des paramètres de mise à jour ? Cela me semble incohérent.

@jpountz Il est également incohérent que l'analyse soit mise à jour via _settings, n'est-ce pas ? Je pense que l'essentiel de la proposition est que nous devrions avoir une API pour les "trucs" pouvant être mis à jour pour un index, qui prend la même forme que la création d'index (c'est-à-dire des sections pour les paramètres, les mappages, etc.). La seule raison pour laquelle nous avons POST /indexname/_settings est que POST /indexname sert à indexer un document ? Nous avons donc besoin d'un suffixe pour signifier "tout ce qui peut être configuré pour un index. Peut-être que POST /indexname/_configuration pourrait être un nouveau gestionnaire, en prenant l'ensemble de la configuration comme décrit ci-dessus. Je pense que cela augmenterait la cohérence (entre création et mise à jour d'index).

@rjernst Je serais d'accord avec cela. Mon commentaire concernait davantage le point de terminaison appelé _settings alors qu'il s'agit en fait de mettre à jour les mappages.

La seule raison pour laquelle nous avons POST /indexname/_settings est que POST /indexname sert à indexer un document ?

En fait, nous utiliserons POST {index}/_doc pour indexer les documents avec des identifiants générés automatiquement, donc je suppose que nous pourrions utiliser POST {index} pour mettre à jour les paramètres/mappages. J'aimerais cependant qu'il soit traité dans un numéro séparé, car celui-ci a déjà une portée très large.

D'après la discussion, je comprends le problème des multi-types dans un index. Je suis d'accord qu'il faut y remédier, mais pas au prix de changements de concepts et d'API. Je pense que la plupart des gens se sont habitués à l'analogie de (db-index, table-type, record-doc) et ont trouvé ES facile à démarrer.

Je pense que cela peut vraiment être quelque chose que l'équipe Elastic gère en interne et probablement facilement. Prenons l'index Twitter comme exemple. S'il existe deux types : tweet et utilisateur, ElasticSearch peut simplement créer deux nouveaux index de type unique derrière la scène comme twitter_tweet et twitter_user, et cela résoudra les problèmes techniques d'indexation.

Pour les API, cela peut et doit toujours être le même qu'avant. Si un utilisateur recherche :

/twitter/?search?q=*

Elasticsearch peut le traduire comme suit, afin qu'il puisse rechercher tous les index.
/twitter_*/?search?q=*

Si un utilisateur recherche tweet "type",

/twitter/tweet/?search?q=*

ES le convertit en :

/twitter_tweet/?search?q=*

Pour plusieurs types

/twitter/tweet,user/?search?q=*

Convertissez-le en
/twitter_tweet,twitter_user/?search?q=*

Pour la cartographie, cela peut être plus compliqué pour l'agrégation. Il y aura un peu de travail dans la traduction des API, mais cela devrait être petit - peut-être que j'ai raté quelque chose ici.

Serait-il préférable de résoudre le vrai problème tout en maintenant la rétrocompatibilité ?

La conception actuelle des types présente l'inconvénient de ressembler à une multilocation par index, ce que nous ne prenons pas bien en charge. Votre suggestion échangerait ce problème contre un autre : trop d'indices Lucene dans un cluster. Avoir plus d'index implique de gérer plus de segments, mais les segments ont des frais généraux et en avoir trop peut causer des problèmes. Nous voyons de tels problèmes avec les utilisateurs qui ont déjà des milliers (ou plus) de partitions par index aujourd'hui.

De plus, la modification que vous suggérez aurait également des implications de compatibilité descendante sur des éléments tels que la notation, étant donné que les statistiques d'index seraient différentes, à moins que l'utilisateur n'opte pour DFS_QUERY_THEN_FETCH.

Enfin, une chose que je n'aime pas avec votre proposition, c'est que si vous pensez à quelqu'un qui commencera à utiliser Elasticsearch dans peut-être deux ans sans connaître l'historique du projet, voir que mettre des documents dans plusieurs index ou types a le même effet , il y aura confusion sur la raison pour laquelle nous avons tous les deux des indices et des types.

Il y aura un peu de travail dans la traduction des API, mais cela devrait être petit - peut-être que j'ai raté quelque chose ici.

Cela peut sembler petit, mais cela laisse une complication dans le fonctionnement du moteur qui n'est pas nécessaire pour la plupart des gens.

Si vous avez besoin de continuer à l'utiliser, je vous suggère de faire cette complication en encapsulant la couche API, en tant que bibliothèque distincte dans votre langue préférée.

Je pense que cela peut vraiment être quelque chose que l'équipe Elastic gère en interne et probablement facilement.

Vous ne le savez peut-être pas, mais c'est un comportement vraiment toxique : http://dilbert.com/strip/1994-10-17

' facile '.

Merci pour les retours. Pour la mise en œuvre, les gars qui y travaillent ont fait un travail formidable et ont certainement plus à dire sur la facilité ou non.

Pour le problème "trop ​​d'indices Lucene dans un cluster", je ne pense pas que ce soit un nouveau problème avec la compatibilité API proposée. Si ES supprime le type dans l'index, nous aurons très probablement plus d'index de toute façon. J'ai trouvé que le mélange des types dans un index par les utilisateurs, comme suggéré dans l'un des articles, n'est pas tout à fait réaliste, à moins qu'il ne s'agisse d'un très petit schéma.

Vraiment, trop d'index est un problème d'implémentation et je ne pense pas que le changement d'implémentation devrait casser les API publiques.

Urgh, c'est tellement ennuyeux, simplement parce que certaines personnes en faisaient une base de données relationnelle. C'était tellement agréable et facile à comprendre d'avoir plusieurs types sous 1 index. Maintenant quoi, je dois avoir plusieurs index ? !

@antonydandrea Vous pouvez créer vous-même un nouveau champ et l'appeler "type", ou quelque chose qui pourrait encore mieux convenir, et filtrer par cela. Ou, si vous stockez des choses très distinctes, il est logique d'utiliser de toute façon plusieurs index. Il y a de très bonnes raisons pour la suppression des types tels qu'ils existent actuellement, comme vous pouvez le lire dans ce fil

Je suis désolé, mais il y a aussi de très bonnes raisons de ne PAS s'en débarrasser aussi. Il était si facile d'avoir différents documents avec différents mappages sous un seul index gérable.

@antonydandrea Que trouvez-vous plus facile avec un index avec plusieurs types par rapport à plusieurs index ou à la gestion de types au-dessus d'Elasticsearch comme décrit par @Felk ?

cc @elastic/es-search-aggs

Mise à jour du plan pour déprécier l'utilisation de include_type_name=true dans 7.x (qui est la valeur par défaut) et échouer dans 8.x, comme discuté avec @rjernst et @clintongormley.

Nous venons de discuter de la façon dont nous voulons mettre à jour les tests REST avec ce changement. Le problème est que la création d'index, l'index, la mise à jour, le mappage put et certaines autres API vont se plaindre avec la version 7.x si le paramètre include_type_name n'est pas défini. Cependant, nous ne voulons pas ignorer tous les tests qui utilisent ces API si la version est < 7.0, car cela désactiverait la plupart des tests lors du test de clusters qui exécutent plusieurs versions. En conséquence, nous nous sommes mis d'accord sur le plan suivant :

  • Utilisez _doc comme nom de type tout le temps.
  • Modifiez le lanceur de test pour ignorer les avertissements indiquant que include_type_name n'est pas défini. Cela permettra aux tests de cluster multi-versions (6.x et 7.0) de continuer à fonctionner comme aujourd'hui. Nous avons fait quelque chose de similaire lors du passage de 5 partitions à 1 partition par défaut (#30539).
  • Tests REST en double pour les API qui prennent désormais en charge le paramètre include_type_name afin de tester le comportement à la fois lorsque include_type_name est défini et lorsqu'il n'est pas défini. Cela ne doit être fait que sur les tests dédiés au test d'une API spécifique. Par exemple, si la création d'index est utilisée comme moyen de configurer des tests, elle ne doit pas être dupliquée alors que si la création d'index elle-même est testée, elle doit être dupliquée.

J'ai mis à jour le plan pour ajouter un nouvel élément à la liste des tâches 7.0 : "supprimer les références aux types de l'API client de repos de haut niveau".

Après avoir vu #33953 @jtibshirani a soulevé la question de savoir si nous voulions faire quelque chose pour que les utilisateurs n'aient pas à passer include_type_name=false à presque toutes les requêtes sur 7.x.

Il est vrai que pour quelqu'un qui résoudrait rapidement les avertissements de dépréciation et utiliserait les nouvelles API sans type, devoir continuer à transmettre include_type_name=false à presque toutes les requêtes semble un peu moche. Pire encore, les nouveaux utilisateurs devraient également passer include_type_name=false pour arrêter de le faire lors de la mise à niveau vers la version 8.0. Ce n'est pas quelque chose qui ne peut pas être géré, mais peut-être pourrions-nous réfléchir à la façon dont nous pouvons améliorer l'expérience ?

Je ne pense pas que nous devrions par défaut include_type_name à true , cela va être trop surprenant et causera des problèmes avec les clusters à versions mixtes. Je pense aussi qu'il est important de donner aux utilisateurs toute une version majeure à mettre à jour : c'est un changement majeur de nos API les plus utilisées (création d'index, indexation de documents, recherche pour n'en citer que quelques-unes).

J'ai envisagé d'ajouter un paramètre de nœud, par exemple. rest.action.include_type_name , pour changer la valeur par défaut de include_type_name pour toutes les API, ce qui ferait essentiellement en sorte que les API se comportent comme dans la version 8.0. Les documents 7.x transmettraient toujours include_type_name=true à toutes les API concernées, car nous ne devrions pas nous attendre à ce que les utilisateurs aient opté pour ce comportement, mais nous pourrions ajouter des notes indiquant qu'ils pourraient ignorer cette configuration sur presque toutes les requêtes grâce à cela. nouveau paramètre de nœud.

Des avis / autres suggestions ? /cc @clintongormley @rjernst

J'ai envisagé d'ajouter un paramètre de nœud, par exemple. rest.action.include_type_name, pour changer la valeur par défaut de include_type_name pour toutes les API, ce qui ferait essentiellement en sorte que les API se comportent comme dans la version 8.0.

J'aime cette idée

@jpountz pour clarifier, lorsque vous faites référence à include_type_name: true dans les deux derniers paragraphes, voulez-vous dire false ?

Serait-il possible de définir par défaut le paramètre sur false pour les nouveaux clusters, afin que les nouveaux utilisateurs de la version 7.0 ne rencontrent jamais le paramètre supplémentaire ? Pour les clients effectuant une mise à niveau à partir d'une version précédente, le paramètre serait plutôt true par défaut. J'essaie juste de réfléchir à un moyen de garder l'expérience prête à l'emploi agréable pour les nouveaux utilisateurs, et je n'ai pas une compréhension parfaite du processus de mise à niveau du cluster/des détails de l'exécution de clusters de versions mixtes.

Une mise à jour : nous nous sommes rencontrés hors ligne pour discuter d'un plan révisé pour la version 7.0, qui est maintenant documenté dans le #35190. Le cœur du plan est défini, mais il reste encore quelques questions ouvertes à régler.

@jpountz Pouvons-nous fermer ce problème maintenant que les types sont obsolètes ?

Nous suivons le travail restant pour la suppression des types dans un autre problème méta maintenant, donc je ferme celui-ci. Vive les genres...

@jpountz @jimczi Je suis confus sur ce problème, pourriez-vous m'aider à l'expliquer ?

Si j'ai un index avec 3 types, comme:

  • type1 : f1 : entier, f2 : entier, f3 : texte
  • type2 : f4 : entier, f5 : texte

alors es (avant la version 5.x) aura 5 champs pour chaque document dans l'index, ce qui conduira à un index clairsemé. je pense à une solution en faisant une transformation lors de la création d'un mappage comme:

  • type1 : champ_entier_1, champ_entier2, champ_texte_1
  • type2 : champ_entier_1, champ_texte_1

donc l'index n'aura que 3 champs :

  • champ_entier_1 : type1.f1, type2.f4
  • champ_entier_2 : type1.f2
  • text_field_1 : type1.f3, type2.f5

lorsque vous interrogez l'index, effectuez simplement la même transformation pour convertir le champ de la requête en champ réel stocké dans l'index. Cela peut-il résoudre le problème de l'index clairsemé ? Ainsi, nous pouvons conserver plusieurs types pour faciliter la modélisation des données.

@penfree Cela fonctionnerait, mais ne serait-il pas encore plus simple d'avoir 2 index ?

@penfree Cela fonctionnerait, mais ne serait-il pas encore plus simple d'avoir 2 index ?

plusieurs doctypes facilitent beaucoup la conception du modèle de données.

Un exemple:
nos données sont le cas d'un patient, elles contiennent plusieurs types de documents, comme

  • informations sur les patients

    • informations sur les visites à la clinique



      • diagnostic


      • rapport de laboratoire


      • rapport d'examen



nous devrions faire une requête sur le diagnostic ou le rapport de laboratoire pour rechercher une visite à la clinique ou un patient, il est difficile de le faire dans plusieurs indices. Sans oublier que nous créons un index par jour et les plaçons dans un alias。

Cette page vous a été utile?
0 / 5 - 0 notes