10

I have a Ticket model and a Comment model. The Ticket has a hasMany relationship to Comment model. I want to search tickets by a keyword. The keyword will be matched againts the subject attribute of the ticket model and the body attribute of the comment model.

The code below doesn't work:

var options = {
  where: {
    $or: [
      {
        subject: {
          like: '%' + query + '%'
        },
      },
      {
        'Comment.body': {
          like: '%' + query + '%'
        },
      }
    ]
  },
  include: [
    { model: Comment },
  ]
};

Ticket.findAll(options);

This is the error: "Possibly unhandled SequelizeDatabaseError: column Ticket.Comment.body does not exist"

I also tried the code below but it also doesn't work:

var options = {
  where: {
    CompanyId: req.company.id,
    $or: [
      {
        subject: {
          like: '%' + query + '%'
        },
      },
      sequelize.cast(sequelize.col('comment.body'), 'TEXT', 'LIKE', '%' + query + '%')
    ]
  },
  include: [
    { model: Comment, as: 'comment', where: {} },
  ]
};

Ticket.findAll(options);

The error is: "Possibly unhandled Error: Comment (comment) is not associated to Ticket!"

And this one:

var options = {
  where: {
    CompanyId: req.company.id,
    $or: [
      {
        subject: {
          like: '%' + query + '%'
        },
      },
      sequelize.where(sequelize.col('Comments.body'), 'LIKE', '%' + query + '%')
    ]
  },
  include: [
    { model: Comment},
  ]
};

Ticket.findAll(options);

Error: "Possibly unhandled SequelizeDatabaseError: missing FROM-clause entry for table "Comments""

I'm using SequelizeJS version 2.0.4

I saw these related issues on the Sequelizejs repository on Github:

Anyone knows a solution? Thanks in advance!

3
  • This is not possible without #3095 - Untill that is implemented, sequelize thinks everything in where is on the main table Commented Jul 8, 2015 at 8:22
  • Thanks @JanAagaardMeier. Hmm. is there no alternative solution? Like make some parts of the code above as raw queries? Or using a full raw query is the only solution for now? Commented Jul 13, 2015 at 20:11
  • github.com/sequelize/sequelize/issues/… Commented May 19, 2016 at 14:24

2 Answers 2

19

Probably a bit too late for you, but for anyone else; #3095 was updated with a bit of a solution:

var options = {
  where: {
    $or: [
      { 'subject': { like: '%' + query + '%' } },
      { '$Comment.body$': { like: '%' + query + '%' } }
    ]
  },
  include: [{ model: Comment }]
};

The trick is in those dollar signs, though there are still problems with this solution when limit is set or when querying with findAndCountAll().

Sign up to request clarification or add additional context in comments.

2 Comments

This can be refactored to use [Sequelize.Op.substring]
and depends on the DB server, probably {[Op.iLike]: `%${i}%`} (for Postgres) would be better choice to have case insensitive search
6
const { Op } = require("sequelize");

var options = {
  where: {
    [Op.or]: [
      { 'subject': { [Op.like]: '%' + query + '%' } },
      { '$Comment.body$': { [Op.like]: '%' + query + '%' } }
    ]
  },
  include: [{ model: Comment }]
};

Op.iLike can be used for case-insensitive search.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.