Maîtriser RediSearch / Partie III

Maîtriser RediSearch / Partie III

Aujourd’hui, nous allons plonger un peu plus profondément et faire quelque chose d’utile avec Node.js, RediSearch et la bibliothèque cliente dans laquelle nous avons commencé Partie II.

Alors que RediRecherche est un excellent moteur de recherche en texte intégral, c’est bien plus que cela et a un pouvoir étendu en tant qu’index secondaire pour Redis. Compte tenu de cela, obtenons un ensemble de données contenant davantage de données basées sur les champs. J’utiliserai l’ensemble de données TMDB (la base de données de films). Vous pouvez télécharger cet ensemble de données à partir du Page Kaggle TMDB. Les données sont formatées en CSV sur deux fichiers et ont quelques fonctionnalités que nous n’allons pas encore utiliser, nous devrons donc créer un script d’ingestion.

Pour suivre, il serait préférable d’obtenir le chapitre-3 branche du dépôt GitHub.

Comprendre la structure du jeu de données

Le premier fichier est tmdb_5000_credits.csv, qui contient les informations sur les acteurs et l’équipe. Bien que les rangées de distribution et d’équipe soient modélisées un peu différemment, elles partagent certaines caractéristiques. Au départ, ce n’est pas un fichier CSV très utilisable puisque deux colonnes (cast, crew) contiennent du JSON.

movie_id (colonne) Cela correspond à une ligne de film dans l’autre fichier.
titre (colonne) Le titre du film identifié avec le movie_id
cast (colonne avec JSON)

  • personnage Le nom du personnage
  • cast_id Un identifiant du personnage dans plusieurs films
  • Nom Le nom de l’acteur ou de l’actrice
  • credit_id A identifiant unique de ce crédit

crew (colonne avec JSON)

  • département Le département ou la catégorie de ce rôle
  • emploi Le nom du rôle sur le plateau
  • Nom Le nom du membre de l’équipage
  • credit_id A identifiant unique de ce crédit

Un autre problème avec le CSV est qu’il est assez énorme pour un fichier de ce type : 40 Mo (à titre de comparaison, le total des œuvres de Shakespeare ne fait que 5,5 Mo). Bien que Node.js puisse gérer des fichiers de cette taille, ce n’est certainement pas si efficace. Pour ingérer ces données de manière optimale, nous utiliserons csv-analyse, un analyseur de flux. Cela signifie que lorsque le fichier CSV est lu, il est également analysé et des événements sont émis. L’analyse en continu est un ajout approprié à RediSearch, déjà très performant.

Chaque ligne du CSV représente un seul film, avec environ 4 800 films dans le fichier. Chaque film, comme vous pouvez l’imaginer, compte des dizaines à des centaines de membres de la distribution et de l’équipe. Au total, vous pouvez vous attendre à indexer environ 235 838 membres de la distribution et de l’équipe, chacun représenté par neuf champs.

L’autre fichier dans le jeu de données TMDB est les données du film. C’est un peu plus simple. Chaque film est une ligne avec quelques colonnes contenant des données JSON. Nous pouvons ignorer ces colonnes de données JSON pour cette partie de la série. Voici comment les champs sont représentés :

movie_id (colonne) A ID unique pour chaque film
budget (colonne) Le budget total du film
original_language (colonne) Version ISO 639–1 de la langue d’origine
titre_original (colonne) Le titre original du film
aperçu (colonne)
Quelques phrases sur le film
popularité (colonne) Classement de popularité du film
release_date (colonne) La date de sortie du film (au format AAAA-MM-JJ)
revenus (colonne) Le montant d’argent qu’il a gagné (USD)
temps d’exécution (colonne) Durée du film (en minutes)
statut (colonne) Le statut de sortie du film (publié » ou « inédit »)

Colonnes ignorées : genres, sociétés_de_production, mots-clés, pays_de_production, langues_parlées

Importation de données depuis TMDB

Maintenant que nous avons exploré à la fois les champs et comment créer un index, avançons dans la création de nos index réels et y insérons des données.

Heureusement, la plupart des données de ces fichiers sont assez propres, mais cela ne signifie pas que nous n’avons pas besoin de faire des ajustements. Dans le fichier distribution/équipe, nous avons le défi que les entrées de distribution et d’équipe aient des ensembles de données légèrement différents. Dans les données, chaque ligne représente un film et la colonne distribution contient tous les acteurs tandis que la colonne équipe contient tous les membres de l’équipe. Ainsi, lorsque nous représentons cela dans le schéma, nous créons effectivement une union des champs (puisqu’il y a un chevauchement). moulage et équipage sont des champs numériques définis sur “1” pour chaque type de crédit – pensez-y comme un drapeau.

redisearch venn

Pour la base de données de films, nous allons convertir date de sortie à un nombre. Nous allons simplement analyser la date dans un horodatage Javascript et le stocker dans un champ numérique. Enfin, nous ignorerons un certain nombre de champs — nous comparerons simplement les clés des colonnes à un tableau de colonnes afin d’ignorer (ignoreFields).

D’une structure de projet, nous pouvons finir par faire plus avec notre fieldDefinitions plus tard, nous stockerons donc les deux schémas dans un module Node.js. C’est purement facultatif mais c’est un modèle propre qui réduit la probabilité d’avoir à dupliquer votre code plus tard.

Pour importer à la fois les films et l’équipe, nous utiliserons une file d’attente Async et l’analyseur CSV en streaming mentionné ci-dessus. Ces deux modules fonctionnent de manière similaire et bien ensemble, mais ont une terminologie différente dans leur syntaxe. Tout d’abord, l’analyseur CSV lira un bloc de données ( parser.on(‘lisible’,…) ) puis continuez à lire une ligne complète à la fois ( while(record = parser.read()){ … } ). Chaque ligne est manipulée et préparée pour RediSearch (csvRecord(enregistrement)). Dans cette fonction, quelques lignes sont formatées tandis que d’autres sont ignorées, et enfin l’élément est poussé dans la file d’attente ( q.pousser(…) ).

Asynchrone est une bibliothèque Javascript très utile qui fournit un grand nombre de métaphores pour gérer le comportement asynchrone. L’implémentation de la file d’attente est assez amusante – les éléments sont poussés dans une file d’attente et sont traités à une simultanéité donnée par une seule fonction de travail définie à l’instanciation. La fonction de travail a deux arguments : l’élément à traiter et un rappel. Une fois le rappel exécuté, le suivant est disponible pour le traitement (jusqu’à la simultanéité donnée). Il y a une super animation qui l’explique :

queue animation
Du asynchrone Documentation

L’autre fonctionnalité de la file d’attente que nous allons utiliser est la drain fonction. Cette fonction s’exécute lorsqu’il ne reste plus d’éléments dans la file d’attente, par exemple la file d’attente était dans un état de fonctionnement mais ne traite plus rien. Il est important de comprendre qu’une file d’attente n’est jamais « terminée », elle devient simplement inactive. Étant donné que nous utiliserons un analyseur de flux, il est possible que RediSearch ingère plus rapidement que l’analyseur CSV, ce qui entraîne une file d’attente Async vide (déclenchant drain). Pour résoudre ce problème potentiel, chaque enregistrement est ajouté à la file d’attente et lorsqu’il est correctement indexé, deux compteurs individuels sont incrémentés (total et traitérespectivement) et l’analyseur CSV définit un analysé variable de “faux” à “vrai”. Donc quand drain est appelé, nous vérifions si analysé est vrai et si la valeur de traité allumettes total. Si ces deux conditions sont vraies, nous savons que toutes les valeurs ont été analysées à partir du CSV et que tout a été ajouté à notre index RediSearch. Après avoir ajouté avec succès un élément à l’index, vous appelez le rappel pour la fonction de travail et la file d’attente gère le reste.

Comme mentionné précédemment, le CSV des crédits est plus complexe, chaque ligne du tableau représentant plusieurs acteurs/membres de l’équipe. Pour gérer cette complexité, je vais utiliser un lot. Nous utiliserons la même structure globale avec l’analyseur CSV et la file d’attente Async, mais chaque ligne contiendra plusieurs appels à RediSearch via le lot (un pour chaque acteur ou membre de l’équipe). Au lieu de pousser un objet simple dans la file d’attente, nous allons en fait pousser un lot RediSearch. Dans la fonction worker nous appellerons exec dessus, puis le rappel. Alors que dans les films CSV, nous aurons une seule commande Redis (RediSearch) par film, dans les crédits CSV, nous aurons un seul lot (composé de dizaines de fonctionnalités individuelles) pour chaque film.

Les deux importations sont suffisamment différentes pour justifier des scripts d’importation distincts. Pour importer les films, vous exécuterez le script comme ceci :

$ node import-tmdb-movies.node.js --connection ./your-connection-object-as.json --data ./path-to-your-movie-csv-file/tmdb_5000_movies.csv

Et les crédits seront importés comme ceci :

$ node import-tmdb-credits.node.js --connection ./your-connection-object-as.json --data ./path-to-your-credits-csv-file/tmdb_5000_credits.csv

Une fonctionnalité intéressante de RediSearch est que dès que vos données sont indexées, elles sont disponibles pour une requête. De vrais trucs en temps réel!

Rechercher les données

Maintenant que nous avons ingéré toutes ces données, écrivons quelques scripts pour les récupérer de RediSearch. Bien que les données soient assez différentes entre les acteurs / l’équipe et les jeux de données du film, nous pouvons écrire un seul et court script pour effectuer la recherche.

Ce petit script vous permettra de passer une chaîne de recherche à partir de la ligne de commande (–search=”votre chaîne de recherche”) et désignez également la base de données dans laquelle vous effectuez la recherche (–searchtype movies ou –searchtype castcrew). Les autres arguments de ligne de commande sont le fichier JSON de connexion (–connection path-to-your-connection-file.json) et des arguments facultatifs pour définir le décalage et le nombre de résultats ( -décalage et –resultsizerespectivement).

Après avoir instancié le module en passant le argv.searchtypenous aurons juste besoin d’utiliser le chercher pour envoyer la requête de recherche et les options en tant qu’objet à RediSearch. Notre bibliothèque de la dernière section s’occupe de construire les arguments qui seront passés au FT.RECHERCHE commande.

Dans le rappel, nous obtenons un rappel d’erreur d’abord très standard. Le deuxième argument contient les résultats de notre recherche, pré-parsés et formatés de manière utile — chaque document a son propre objet avec deux propriétés : doc et docId. Le docId contient l’identifiant unique et le document en tant qu’objet.

Tout ce que nous devons faire est JSON.stringify les résultats (ainsi console.log ne s’affichera pas [Object object]) puis quittez le client.

Vous pouvez l’essayer en exécutant la commande suivante :

$ node search.node.js --connection ./your-connection-object-as.json --search="star" --searchtype movies --offset 0 --resultsize 1

Cela devrait renvoyer une entrée sur le film étoile solitaire (quelqu’un l’a vu? Non, je ne le pensais pas). Maintenant, regardons dans l’index cast/crew pour tout ce qui a le même move_id :

$ node search.node.js --connection ./your-connection-object-as.json --search="@movie_id:[26748 26748]" --searchtype castCrew

Cela vous donnera les dix premiers éléments de la distribution et de l’équipe de Lone Star. Semble simple à l’exception de la chaîne de recherche – pourquoi devez-vous répéter 26748 deux fois ? Dans ce cas, c’est parce que le movie_id champ dans la base de données est numérique et les valeurs numériques ne peuvent être limitées que par une plage.

Saisir un document

Obtenir un document de RediSearch est encore plus simple. Fondamentalement, nous instancions tout de la même manière que nous l’avons fait avec le script de recherche, mais nous n’avons pas besoin de fournir d’options et au lieu d’une chaîne de recherche, nous obtenons un IDdoc.

Il nous suffit de passer le IDdoc au obtenirDoc méthode (abstraction de la FT.GET commande) avec un rappel et nous sommes en affaires ! La Afficher la fonction est la même que dans la recherche.

Cela fonctionnera aussi bien pour les acteurs/l’équipe que pour les documents de film :

$ node by-docid.node.js --connection ./your-connection-object-as.json --docid="56479e8dc3a3682614004934" --searchtype castCrew

Suppression de l’index

Si vous essayez d’importer un fichier CSV deux fois, vous obtiendrez une erreur semblable à celle-ci :

if (err) { throw err; }
ReplyError: Index already exists. Drop it first!

En effet, vous ne pouvez pas simplement créer un index sur un index préexistant. Un script est inclus pour supprimer rapidement l’un de vos index. Vous pouvez l’exécuter comme ceci :

$ node drop-index.node.js --connection ./your-connection-object-as.json --searchtype movies

Statut et prochaines étapes

Dans cet article, nous avons expliqué comment analyser de gros fichiers CSV et les importer efficacement dans RediSearch avec quelques scripts adaptés à leurs différentes structures. Ensuite, nous avons créé un script pour exécuter des requêtes de recherche sur ces données, récupérer des documents individuels et supprimer un index. Nous avons maintenant appris la plupart des étapes de gestion du cycle de vie d’un jeu de données.

Dans notre prochain article, nous allons créer quelques fonctionnalités supplémentaires dans notre bibliothèque pour améliorer la recherche abstraite et ajouter quelques options supplémentaires. Ensuite, nous commencerons à créer une interface utilisateur Web pour rechercher dans nos données. Restez à l’écoute du blog Redis !

Development Source

Related Posts

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

RLEC 4.2.1 apporte des contrôles granulaires à la haute disponibilité et aux performances

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Comment HolidayMe utilise Redis Enterprise comme base de données principale

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Annonce de RedisGears 1.0 : un moteur sans serveur pour Redis

Clés Redis dans la RAM |  Redis

Clés Redis dans la RAM | Redis

No Comment

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *