代码之家  ›  专栏  ›  技术社区  ›  Kerim092

如何连续查询多对多关系

  •  5
  • Kerim092  · 技术社区  · 6 年前

    我已经通过Sequelize在PostgresDB上使用了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'

    但它不起作用,因为没有“参与者”这样的列,所以我不能查询它。所以现在我只是提取所有事件并在after hook中为当前用户过滤它们,但这似乎是错误的。正确的方法是什么?

    是的,我知道我可以通过将用户包含到用户中并获取他来获得用户是参与者之一的事件,但问题是我不能将所有数据排序在一起,它是分开排序的,另一个问题是在前端进行分页。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Daff    6 年前

    查询嵌套关联不是Feather公共查询语法的一部分。在排序的情况下,应根据需要使用 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);
    }
    
        2
  •  0
  •   Kerim092    6 年前

    在@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)
        ],
    .........
    
    推荐文章