如何查询多对多关系

时间:2018-07-30 01:03:31

标签: sequelize.js feathersjs feathers-sequelize

我一直在通过sequelize在postgres db上使用feathersjs / nodejs。在我的数据库中,我有用户表和事件表。他们是两次关系:

events.belongsTo(models.users, {
  foreignKey: {
    name: 'creatorId',
    allowNull: false
  },
  onDelete: 'CASCADE',
  as: 'creator'
});

events.belongsToMany(models.users, {
  through: 'event_participants',
  as: 'participants',
  foreignKey: 'eventId',
  otherKey: 'userId'
});
models.users.belongsToMany(events, {
  through: 'event_participants',
  as: 'events'
});

一切正常,创建表,并包含将用户作为参与者吸引到事件内部。问题是通过关联查询。我正在尝试获取当前用户的事件,因此我需要创建者为当前用户的事件和参与者之一为当前用户的事件。问题是第二部分“查询当前用户是参与者之一”。我期待这样的事情

'api/events?$or[0][creatorId]=currUserId&$or[1][participants][$contains]=currUserId'

但是它不起作用,因为没有包含“参与者”这样的列,所以我无法查询它。因此,到目前为止,我只是获取所有事件并在之后的钩子中为当前用户过滤它们,但这似乎是错误的。什么是正确的方法?

是的,我知道我可以通过将事件包含在用户中并获取他来获取用户是参与者之一的事件,但是问题是我无法将这些数据全部分类在一起,将其分别分类,另一个问题是前端的分页

2 个答案:

答案 0 :(得分:2)

查询嵌套关联不是Feathers通用查询语法的一部分。在使用Sequelize的情况下,应根据您的需求使用params.sequelize来组装查询,并按照feathers-sequelize associations documentation所示进行查询:

// GET /my-service?name=John&include=1
function (context) {
   if (context.params.query.include) {
      const AssociatedModel = context.app.services.fooservice.Model;
      context.params.sequelize = {
         include: [{
           model: AssociatedModel
           // normal Sequelize where query here
          }]
      };
      // delete any special query params so they are not used
      // in the WHERE clause in the db query.
      delete context.params.query.include;
   }

   return Promise.resolve(context);
}

答案 1 :(得分:0)

借助@daff的答案,我发现了这样的解决方案... here就是我遇到的错误。

const { authenticate } = require('@feathersjs/authentication').hooks;

function includeBefore(hook) {
  currUserId = hook.params.user.id;
  userModel = hook.app.services.users.Model
  hook.params.sequelize = {
    where: {
      $or: [
        {
          creatorId: currUserId
        },
        {
          '$participants.id$': currUserId  //no idea what are '$$' for but it made it work
        }
      ]
    },
    include: [
      {
        model: userModel,
        as: 'creator',
      }, {
        model: userModel,
        as: 'participants',
        duplicating: false //fixed error that I was getting 
      }
    ],
  }
  return hook;
}


module.exports = {
  before: {
    all: [
      authenticate('jwt'),
      hook => includeBefore(hook)
    ],
.........