Comment utiliser la recherche plein texte dans MongoDB?

Ordinateur portable

MongoDB, l’une des principales bases de donnĂ©es NoSQL, est bien connue pour ses performances rapides, son schĂ©ma flexible, son Ă©volutivitĂ© et ses grandes capacitĂ©s d’indexation. Au cƓur de ces performances rapides se trouvent les index MongoDB, qui support exĂ©cution efficace des requĂȘtes en Ă©vitant les balayages de collections complĂštes et en limitant ainsi le nombre de documents que MongoDB recherche.

À partir de la version 2.4, MongoDB a commencĂ© avec une fonctionnalitĂ© expĂ©rimentale prenant en charge la recherche plein texte Ă  l’aide d’index de texte. Cette fonctionnalitĂ© fait dĂ©sormais partie intĂ©grante du produit (et n’est plus une fonctionnalitĂ© expĂ©rimentale). En utilisant la recherche plein texte de MongoDB, vous pouvez dĂ©finir un index de texte sur n’importe quel champ du document dont la valeur est une chaĂźne ou un tableau de chaĂźnes. Lorsque nous crĂ©ons un index de texte sur un champ, MongoDB tokenise et dĂ©coupe le contenu textuel du champ indexĂ©, et configure les index en consĂ©quence.

Dans ce tutoriel, nous allons explorer les fonctionnalités de recherche en texte intégral de MongoDB.

CRÉATION D’UN SERVEUR MONGODB SUR HIDORA

Tout d’abord, nous devons installer MongoDB, alors voyons comment MongoDB peut ĂȘtre installĂ© rapidement et facilement sur le PaaS Hidora :

  • Connectez-vous au tableau de bord Hidora avec vos informations d’identification.
  • Cliquez sur CrĂ©er un environnement dans le coin supĂ©rieur gauche du tableau de bord.
  • Dans la boĂźte de dialogue Topologie de l’environnement, choisissez MongoDB comme base de donnĂ©es Ă  utiliser (elle se trouve dans la liste dĂ©roulante des bases de donnĂ©es NoSQL). DĂ©finissez les limites de cloudlet pour ce nƓud, tapez le nom de votre premier environnement et confirmez la crĂ©ation.

select mangoDB

  • Attendez une minute que le processus soit terminĂ©.

environment created hidora

 

CONNEXION À LA MONGODB AVEC SSH

Voyons maintenant comment vous pouvez accéder à votre compte Hidora avec tous ses environnements et conteneurs.

Note. L’accĂšs SSH est fourni Ă  l’ensemble du compte mais pas Ă  un environnement sĂ©parĂ©.

  • Ouvrez le tableau de bord Hidora et accĂ©dez Ă  la barre d’outils supĂ©rieure.
  • Cliquez sur le bouton ParamĂštres.

settings Hidora

Dans l’onglet ParamĂštres du compte ouvert, accĂ©dez Ă  l’option Trousseau de clĂ©s SSH > Public.

Note. La disponibilitĂ© de cette option n’est activĂ©e que pour les clients qui facturent. Si vous avez besoin de cet accĂšs pendant la pĂ©riode d’essai, faites-le nous savoir et nous vous accorderons l’accĂšs nĂ©cessaire.

  • Cliquez sur le lien dans la note pour ouvrir votre porte SSH. Ainsi, vous accĂ©derez automatiquement au Shell Handler via la console. Ou bien, copiez simplement la ligne de commande donnĂ©e et exĂ©cutez-la via votre console (client SSH).

Putty gateway hidora

CRÉATION D’UN ÉCHANTILLON DE DONNÉES

Les donnĂ©es dans MongoDB ont un schĂ©ma flexible. Contrairement aux bases de donnĂ©es SQL, oĂč vous devez dĂ©terminer et dĂ©clarer le schĂ©ma d’une table avant d’insĂ©rer des donnĂ©es, les collections de MongoDB n’imposent pas la structure des documents. Cette flexibilitĂ© facilite la mise en correspondance des documents avec une entitĂ© ou un objet. Chaque document peut correspondre aux champs de donnĂ©es de l’entitĂ© reprĂ©sentĂ©e, mĂȘme si les donnĂ©es prĂ©sentent des variations importantes. En pratique, cependant, les documents d’une collection partagent une structure similaire.

Le principal dĂ©fi de la modĂ©lisation des donnĂ©es consiste Ă  trouver un Ă©quilibre entre les besoins de l’application, les caractĂ©ristiques de performance du moteur de base de donnĂ©es et les modĂšles de rĂ©cupĂ©ration des donnĂ©es. Lors de la conception des modĂšles de donnĂ©es, il faut toujours prendre en compte l’utilisation des donnĂ©es par l’application (c’est-Ă -dire les requĂȘtes, les mises Ă  jour et le traitement des donnĂ©es) ainsi que la structure inhĂ©rente des donnĂ©es elles-mĂȘmes.

MongoDB stocke les enregistrements de donnĂ©es sous forme de documents BSON. BSON est une reprĂ©sentation binaire des documents JSON, bien qu’il contienne plus de types de donnĂ©es que JSON. Pour la spĂ©cification BSON, voir bsonspec.org.

MongoDB stocke les documents BSON, c’est-Ă -dire les enregistrements de donnĂ©es, dans des collections ; les collections dans des bases de donnĂ©es. Dans MongoDB, les bases de donnĂ©es contiennent des collections de documents.

To select a database to use, in the mongo shell, issue the use <db> statement, as in the following example:

utiliser myDB

Créer une base de données

Si une base de donnĂ©es n’existe pas, MongoDB crĂ©e la base de donnĂ©es lorsque vous stockez pour la premiĂšre fois des donnĂ©es pour cette base de donnĂ©es. Ainsi, vous pouvez passer Ă  une base de donnĂ©es inexistante et effectuer l’opĂ©ration suivante dans le shell mongo :

use myNewDB
db.myNewCollection1.insertOne( { x: 1 } )

L’opĂ©ration insertOne() crĂ©e Ă  la fois la base de donnĂ©es maNouvelleDB et la collection maNouvelleCollection1 si elles n’existent pas dĂ©jĂ .

MongoDB stocke les documents dans des collections. Les collections sont analogues aux tables des bases de données relationnelles.

Créer une collection

Si une collection n’existe pas, MongoDB crĂ©e la collection lorsque vous stockez pour la premiĂšre fois des donnĂ©es pour cette collection.

db.myNewCollection2.insertOne( { x: 1 } )
db.myNewCollection3.createIndex( { y: 1 } )

Les opĂ©rations insertOne() et createIndex() crĂ©ent leur collection respective si elle n’existe pas dĂ©jĂ .

Création explicite

MongoDB fournit la mĂ©thode db.createCollection() pour crĂ©er explicitement une collection avec diverses options, comme la dĂ©finition de la taille maximale ou les rĂšgles de validation de la documentation. Si vous ne spĂ©cifiez pas ces options, vous n’avez pas besoin de crĂ©er explicitement la collection puisque MongoDB crĂ©e de nouvelles collections lorsque vous stockez pour la premiĂšre fois des donnĂ©es pour les collections.

RECHERCHE DE DOCUMENTS

À partir de MongoDB 3.2, MongoDB introduit une version 3 de l’index texte

MongoDB fournit des index de texte pour support des requĂȘtes de recherche de texte sur le contenu des chaĂźnes de caractĂšres. Les index de texte peuvent inclure tout champ dont la valeur est une chaĂźne de caractĂšres ou un tableau d’Ă©lĂ©ments de chaĂźne de caractĂšres.

Créer un index de texte

IMPORTANT : Une collection peut avoir au maximum un index texte.

Pour crĂ©er un index de texte, utilisez la mĂ©thode db.collection.createIndex(). Pour indexer un champ qui contient une chaĂźne de caractĂšres ou un tableau d’Ă©lĂ©ments de chaĂźne de caractĂšres, incluez le champ et spĂ©cifiez le littĂ©ral de chaĂźne de caractĂšres « text » dans le document d’index, comme dans l’exemple suivant :

db.reviews.createIndex( { comments: “text” } )

Vous pouvez indexer plusieurs champs pour l’index texte. L’exemple suivant crĂ©e un index texte sur les champs sujet et commentaires :

db.reviews.createIndex( { subject: “text”, comments: “text” } )

Un index composĂ© peut inclure des clĂ©s d’index texte en combinaison avec des clĂ©s d’index ascendantes ou descendantes. Pour dĂ©poser un index texte, il faut utiliser le nom de l’index.

Précisez le poids

Pour un index de texte, le poids d’un champ indexĂ© indique l’importance de ce champ par rapport aux autres champs indexĂ©s en termes de score de recherche de texte.

Pour chaque champ indexé du document, MongoDB multiplie le nombre de correspondances par le poids et additionne les résultats. En utilisant cette somme, MongoDB calcule ensuite le score du document.

Le poids par dĂ©faut est de 1 pour les champs indexĂ©s. Pour ajuster les pondĂ©rations des champs indexĂ©s, incluez l’option weights dans la mĂ©thode db.collection.createIndex().

Index des textes des cartes de vƓux

Lorsque vous crĂ©ez un index texte sur plusieurs champs, vous pouvez Ă©galement utiliser le spĂ©cificateur de caractĂšre gĂ©nĂ©rique ($**). Avec un index de texte avec caractĂšre de remplacement, MongoDB indexe chaque champ contenant des donnĂ©es de type chaĂźne pour chaque document de la collection. L’exemple suivant crĂ©e un index texte en utilisant le spĂ©cificateur de caractĂšre gĂ©nĂ©rique :

db.collection.createIndex( { “$**”: “text” } )

Cet index permet d’effectuer des recherches textuelles sur tous les champs contenant des chaĂźnes de caractĂšres. Un tel index peut ĂȘtre utile avec des donnĂ©es trĂšs peu structurĂ©es si l’on ne sait pas quels champs inclure dans l’index textuel ou pour des requĂȘtes ad-hoc.

Les index de texte avec caractĂšres gĂ©nĂ©riques sont des index de texte sur plusieurs champs. En tant que tels, vous pouvez attribuer des pondĂ©rations Ă  des champs spĂ©cifiques lors de la crĂ©ation de l’index afin de contrĂŽler le classement des rĂ©sultats.

Les index de texte avec caractĂšres gĂ©nĂ©riques, comme tous les index de texte, peuvent faire partie d’un index composĂ©. Par exemple, l’exemple suivant crĂ©e un index composĂ© sur le champ a ainsi que sur le spĂ©cificateur de caractĂšre gĂ©nĂ©rique :

db.collection.createIndex( { a: 1, “$**”: “text” } )

Comme pour tous les index textuels composĂ©s, puisque le a prĂ©cĂšde la clĂ© de l’index textuel, pour effectuer une recherche $text avec cet index, le prĂ©dicat de la requĂȘte doit inclure une condition d’Ă©galitĂ© a.

Insensibilité aux cas

L’index de texte de la version 3 prend en charge les pliages de casse communs C, simples S et, pour les langues turques, les pliages de casse spĂ©ciaux T, comme spĂ©cifiĂ© dans la base de donnĂ©es de caractĂšres Unicode 8.0 Case Folding.

Le pliage en casse Ă©tend l’insensibilitĂ© Ă  la casse de l’index du texte pour inclure les caractĂšres avec diacritiques, comme Ă© et É, et les caractĂšres des alphabets non latins, comme « И » et « О » dans l’alphabet cyrillique.

La version 3 de l’index textuel est Ă©galement insensible aux diacritiques . Ainsi, l’index ne fait pas non plus la distinction entre Ă©, É, e et E.

Les versions prĂ©cĂ©dentes de l’index textuel sont insensibles Ă  la casse pour [A-z] seulement ; c’est-Ă -dire insensibles Ă  la casse pour les caractĂšres latins non diacritiques seulement. Pour tous les autres caractĂšres, les versions prĂ©cĂ©dentes de l’index textuel les traitent comme distincts.

Insensibilité aux diacritiques

Avec la version 3, l’index textuel est insensible aux signes diacritiques. En d’autres termes, l’index ne fait pas de distinction entre les caractĂšres qui contiennent des signes diacritiques et leurs homologues non marquĂ©s, tels que Ă©, ĂȘ et e. Plus prĂ©cisĂ©ment, l’index textuel Ă©limine les caractĂšres classĂ©s comme diacritiques dans la CharacterDatabase Prop List de Unicode 8.0.

La version 3 de l’index textuel est Ă©galement insensible Ă  la casse des caractĂšres avec diacritiques. Ainsi, l’index ne fait pas non plus la distinction entre Ă©, É, e et E.

Les versions prĂ©cĂ©dentes de l’index textuel traitent les caractĂšres avec diacritiques comme distincts.

DĂ©limiteurs de tokenisation

Pour la tokenisation, l’index de texte de la version 3 utilise les dĂ©limiteurs catĂ©gorisĂ©s sous Dash, Hyphen, Pattern_Syntax, Quotation_Mark, Terminal_Punctuation, et White_Space dans la liste Prop de la base de donnĂ©es de caractĂšres Unicode 8.0.

Par exemple, si on lui donne la chaĂźne « Il a dit qu’il « était le meilleur joueur du monde » », l’index textuel traite les « ,  » et les espaces comme des dĂ©limiteurs.

Les versions prĂ©cĂ©dentes de l’index traitent  » comme une partie du terme «  »était » » et  » comme une partie du terme « monde » ».

EntrĂ©es d’index

L’index textuel tokenise et strie les termes dans les champs indexĂ©s pour les entrĂ©es d’index. L’index textuel stocke une entrĂ©e d’index pour chaque terme unique Ă©purĂ© dans chaque champ indexĂ© pour chaque document de la collection. L’index utilise un stemmage simple par suffixe spĂ©cifique Ă  la langue.

Langues prises en charge et mots d’arrĂȘt

MongoDB prend en charge la recherche de texte dans plusieurs langues. Les index de texte ne tiennent pas compte des mots d’arrĂȘt spĂ©cifiques Ă  la langue (par exemple, en anglais, the, an, a, and, etc.) et utilisent des suffixes simples spĂ©cifiques Ă  la langue. Pour obtenir une liste des langues prises en charge, consultez la rubrique Langues de recherche de texte.

Si vous spĂ©cifiez la valeur « none » pour la langue, l’indexation du texte utilise une simple tokĂ©nisation sans liste de mots d’arrĂȘt ni dĂ©rivation.

Propriété éparse

Les index de texte sont Ă©pars par dĂ©faut et ignorent l’option sparse : true. Si un document n’a pas de champ d’index texte (ou si le champ est nul ou un tableau vide), MongoDB n’ajoute pas d’entrĂ©e pour le document Ă  l’index texte. Pour les insertions, MongoDB insĂšre le document mais n’ajoute rien Ă  l’index de texte.

Pour un index composĂ© qui comprend une clĂ© d’indexation de texte ainsi que des clĂ©s d’autres types, seul le champ d’indexation de texte dĂ©termine si l’index fait rĂ©fĂ©rence Ă  un document. Les autres clĂ©s ne dĂ©terminent pas si l’index fait rĂ©fĂ©rence aux documents ou non.

Restrictions

Un seul index de texte par collection. Une collection peut avoir au maximum un index texte.

Recherche de texte et conseils

Vous ne pouvez pas utiliser hint() si la requĂȘte comprend une expression de requĂȘte $text.

Index et tri de texte

Les opĂ©rations de tri ne peuvent pas obtenir l’ordre de tri Ă  partir d’un index de texte, mĂȘme d’un index de texte composĂ© ; c’est-Ă -dire que les opĂ©rations de tri ne peuvent pas utiliser l’ordre de l’index de texte.

Indice composé

Un index composĂ© peut inclure une clĂ© d’indexation de texte en combinaison avec des clĂ©s d’indexation ascendantes/descendantes. Toutefois, ces index composĂ©s prĂ©sentent les restrictions suivantes :

  • Un index textuel composĂ© ne peut pas inclure d’autres types d’index spĂ©ciaux, tels que des champs d’index Ă  clĂ©s multiples ou gĂ©ospatiaux.
  • Si l’index textuel composĂ© comprend des clĂ©s prĂ©cĂ©dant la clĂ© de l’index textuel, pour effectuer une recherche $text, le prĂ©dicat de la requĂȘte doit inclure des conditions de correspondance d’Ă©galitĂ© sur les clĂ©s prĂ©cĂ©dentes.

DĂ©poser un index de texte

Pour supprimer un index de texte, passez le nom de l’index Ă  la mĂ©thode db.collection.dropIndex(). Pour obtenir le nom de l’index, exĂ©cutez la mĂ©thode db.collection.getIndexes().

Exigences de stockage et coûts de performance

Les index de texte ont les exigences de stockage et les coûts de performance suivants :

  • Les index de texte peuvent ĂȘtre volumineux. Ils contiennent une entrĂ©e d’index pour chaque mot unique post-sĂ©quencĂ© dans chaque champ indexĂ© pour chaque document insĂ©rĂ©.
  • La construction d’un index textuel est trĂšs similaire Ă  la construction d’un grand index multi-clĂ© et prendra plus de temps que la construction d’un simple index ordonnĂ© (scalaire) sur les mĂȘmes donnĂ©es.
  • Lorsque vous construisez un index de texte volumineux sur une collection existante, assurez-vous que vous disposez d’une limite suffisamment Ă©levĂ©e de descripteurs de fichiers ouverts.
  • Les index de texte auront un impact sur le dĂ©bit d’insertion car MongoDB doit ajouter une entrĂ©e d’index pour chaque mot unique post-sĂ©quencĂ© dans chaque champ indexĂ© de chaque nouveau document source.
  • En outre, les index de texte ne stockent pas les phrases ou les informations sur la proximitĂ© des mots dans les documents. Par consĂ©quent, les requĂȘtes de phrases s’exĂ©cutent beaucoup plus efficacement lorsque la collection entiĂšre tient dans la mĂ©moire vive.

Recherche de texte Support

L’index texte supporte les opĂ©rations de recherche $text. Pour des exemples de recherche de texte, voir la page de rĂ©fĂ©rence $text. Pour des exemples d’opĂ©rations $text dans les pipelines d’agrĂ©gation, voir Recherche de texte dans le pipeline d’agrĂ©gation.

EXISTE-T-IL UN MOYEN D’AMÉLIORER LES PERFORMANCES ?

La recherche en texte intĂ©gral ne fonctionne pas correctement pour les ensembles de donnĂ©es trĂšs volumineux, car toutes les correspondances sont renvoyĂ©es sous la forme d’un document unique et la commande n’est pas support un paramĂštre « skip » pour rĂ©cupĂ©rer les rĂ©sultats page par page. Bien que la recherche ne porte que sur le champ « _id », un Ă©norme ensemble de rĂ©sultats ne sera pas renvoyĂ© dans son intĂ©gralitĂ© si le rĂ©sultat dĂ©passe la limite de 16 Mo par document fixĂ©e par Mongo. Un index textuel composĂ© ne peut pas inclure d’autres types d’index, comme les index multi-clĂ© ou les index gĂ©o-spatiaux. De plus, si votre index textuel composĂ© comprend des clĂ©s d’indexation avant la clĂ© d’indexation textuelle, toutes les requĂȘtes doivent spĂ©cifier les opĂ©rateurs d’Ă©galitĂ© pour les clĂ©s prĂ©cĂ©dentes. Les index de texte crĂ©ent une surcharge lors de l’insertion de nouveaux documents. Cela a pour effet de rĂ©duire le dĂ©bit d’insertion. Certaines requĂȘtes, comme les recherches de phrases, peuvent ĂȘtre relativement lentes.

CONCLUSION

La recherche en texte intĂ©gral de MongoDB n’est pas proposĂ©e comme un remplacement complet des bases de donnĂ©es Ă  moteur de recherche comme Elastic, SOLR, etc. Cependant, elle peut ĂȘtre utilisĂ©e efficacement pour la majoritĂ© des applications qui sont construites avec MongoDB aujourd’hui.

Écrit par

Matthieu Robin Hidora
Matthieu ROBIN
16/11/2017

Matthieu Robin est le CEO de Hidora, un leader stratĂ©gique expĂ©rimentĂ©, un ancien administrateur systĂšme qui a gĂ©rĂ© et configurĂ© plus d’environnements manuellement que quiconque sur la planĂšte et aprĂšs avoir compris que cela pouvait ĂȘtre fait en quelques clics a crĂ©Ă© Hidora SA. Il intervient rĂ©guliĂšrement lors de confĂ©rences et aide les entreprises Ă  optimiser leurs processus mĂ©tier grĂące Ă  DevOps. Suivez-le sur Twitter @matthieurobin.