web-dev-qa-db-fra.com

Recherche séquentielle basée sur l'association

Comment utiliser Sequelize pour trouver toutes les personnes où une colonne dans la relation satisfait une condition?

Un exemple serait de trouver tous les livres dont le nom de famille de l'auteur est "Hitchcock". Le schéma du livre contient une relation hasOne avec la table de l'auteur.

Edit: je comprends comment cela pourrait être fait avec une requête SQL brute, mais à la recherche d'une autre approche

34
futbolpal

Voici un exemple de travail sur la façon d'utiliser Sequelize pour obtenir tous les Books par un Author avec un certain nom de famille. Cela semble un peu plus compliqué qu'il ne l'est, car je définis les modèles, les associe, me synchronise avec la base de données (pour créer leurs tables), puis crée des données factices dans ces nouvelles tables. Recherchez le findAll au milieu du code pour voir précisément ce que vous recherchez.

    module.exports = function(sequelize, DataTypes) {

    var Author = sequelize.define('Author', {

        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        firstName: {
            type: DataTypes.STRING
        },
        lastName: {
            type: DataTypes.STRING
        }

    })

    var Book = sequelize.define('Book', {

        id: {
            type: DataTypes.INTEGER,
            allowNull: false,
            autoIncrement: true,
            primaryKey: true
        },
        title: {
            type: DataTypes.STRING
        }

    })

    var firstAuthor;
    var secondAuthor;

    Author.hasMany(Book)
    Book.belongsTo(Author)

    Author.sync({ force: true })
        .then(function() {
            return Book.sync({ force: true });
        })
        .then(function() {
            return Author.create({firstName: 'Test', lastName: 'Testerson'});
        })
        .then(function(author1) {
            firstAuthor=author1;
            return Author.create({firstName: 'The Invisible', lastName: 'Hand'});
        })
        .then(function(author2) {
            secondAuthor=author2
            return Book.create({AuthorId: firstAuthor.id, title: 'A simple book'});
        })
        .then(function() {
            return Book.create({AuthorId: firstAuthor.id, title: 'Another book'});
        })
        .then(function() {
            return Book.create({AuthorId: secondAuthor.id, title: 'Some other book'});
        })
        .then(function() {
            // This is the part you're after.
            return Book.findAll({
                where: {
                   'Authors.lastName': 'Testerson'
                },
                include: [
                    {model: Author, as: Author.tableName}
                ]
            });
        })
        .then(function(books) { 
            console.log('There are ' + books.length + ' books by Test Testerson')
        });
  }
28
c.hill

Dans la dernière version de Sequilize (5.9.0), la méthode proposée par @ c.hill ne fonctionne pas.

Vous devez maintenant effectuer les opérations suivantes:

return Book.findAll({
    where: {
        '$Authors.lastName$': 'Testerson'
    },
    include: [
        {model: Author, as: Author.tableName}
    ]
});
2
Adam