1
votes

Sequelize: Comment vérifier si une sous-chaîne existe dans une table

Existe-t-il un moyen de vérifier si une chaîne particulière existe dans une colonne d'une table?

Par exemple, j'ai une table 'fruits' avec deux colonnes, clé primaire et fruit_name et les lignes suivantes

XXX

J'ai un exemple de chaîne nommé apple_shake. J'ai besoin de vérifier si une sous-chaîne de ce apple_shake existe. La requête doit renvoyer la ligne contenant 'apple'

Je sais comment cela peut être fait dans la requête mysql - SQL - Requête pour trouver si une chaîne contient une partie de la valeur dans Column

Mais grâce à sequelize, le suivi a un problème

var sample_fruit_string = "apple_shake";
var gsp_config  = await model.fruit.findOne({where: {
    fruit_name: {
        [Op.like]: sample_fruit_string + '%'
    }
}});


7 commentaires

Vous faites "apple" LIKE "apple_shake%" , mais vous voulez l'inverse: "apple_shake" LIKE "apple" . Bien que je ne sache pas encore comment exprimer cela avec sequelize.js .


Précisément! Je pourrais le faire via une requête brute. Mais je ne suis pas en mesure de faire une requête via le modèle sequelize. Peut-être devrais-je utiliser la requête directement au lieu de me fier au modèle?


La requête brute devrait fonctionner. De plus, je pense que vous pouvez exprimer cela en utilisant la fonction MySQL LOCATE () - sequelize.js prend en charge les fonctions, et je pense que vous pouvez l'exprimer dans le cadre de votre où: expression dans le code ci-dessus. Pour COUNT () , l'exemple ressemblerait à ceci: sequelize.fn ('COUNT', sequelize.col ('table_column_name')) , et vous pouvez probablement étendre cela pour fonctionner avec LOCATE () . Mais je suppose ici, pas de réelle expérience avec cette bibliothèque.


Ce n'est pas un problème avec Sequelize, ce type de requête n'est pas possible avec SQL


@alx LOCATE () est comme indexof, cela ne fonctionnera pas pour cet exemple. Vous devrez décomposer l'entrée et effectuer une requête itérative, ce qui ne sera pas très efficace. Si vous pouvez faire quelque chose comme diviser l'entrée sur _ , vous pourrez alors utiliser un LIKE normal.


@doublesharp Je ne comprends pas pourquoi vous dites que c'est impossible, regardez ce sqlfiddle: sqlfiddle. com / #! 9 / 4c8192 / 2 . J'ai également des préoccupations concernant l'efficacité, mais pas la possibilité en tant que telle.


@alx je reste corrigé - je ne savais pas que vous pouviez inverser les entrées comme ça et le faire fonctionner. Je m'interroge cependant sur l'efficacité avec un ensemble de données plus grand.


3 Réponses :


2
votes

Merci à @alx pour le SQL que je ne savais pas possible - c'est ainsi que vous générez le SQL approprié avec Sequelize. Notez que cela peut ne pas être efficace avec de grands ensembles de données.

SELECT `id` FROM `fruit` AS `fruit` WHERE LOCATE(`fruit_name`, 'apple_shake') != 0 LIMIT 1;

Génère les éléments suivants:

const sample_fruit_string = "apple_shake"; 

const gsp_config = await model.fruit.findOne({
  attributes: ['id'],
  where: Sequelize.where(
      Sequelize.fn('LOCATE', Sequelize.col('fruit_name'), sample_fruit_string),
      Sequelize.Op.ne,
      0
  ),
  logging: true,
});


1 commentaires

Génial! Fonctionne comme un charme. Pas sûr de la performance cependant. Et je n'ai jamais su que c'était aussi compliqué. Trouver une super chaîne est simple, mais trouver une sous-chaîne est assez difficile




0
votes
var sample_fruit_string = "apple_shake";
var gsp_config  = await model.fruit.findOne({where: {
fruit_name: {
    [Op.like]: `%${sample_fruit_string}%` // LIKE '%sample_fruit_string%'
   //  [Op.ilike]: `%${sample_fruit_string}%` // For case sensitive searching
   // [Op.substring]: sample_fruit_substring  // Has been depreciated in future version of sequelize.
}
}});

0 commentaires