"外连接"父母没有参考

时间:2016-01-27 06:46:28

标签: mongodb mongoose mongoose-populate

我有以下猫鼬模型(摘录):

var subscriberSchema = new Schema({
  name: String,
  address: String
});
var Subscriber = mongoose.model('Subscriber', subscriberSchema);

var magazineSchema = new Schema({
  title: String
});
var Magazine = mongoose.model('Magazine', magazineSchema);

var subscriptionSchema = new Schema({
  owner: {type: Schema.Types.ObjectId, ref: 'Subscriber'},
  magazine: {type: Schema.Types.ObjectId, ref: 'Magazine'},
  metadata like price, start date, end date: ...
});
var Subscription = mongoose.model('Subscription', subscriptionSchema);

我有一条快速路线,向用户显示杂志列表:

let magazines = await Magazine.find();
if (!magazines) return next(err);

res.render('magazines', {
  magazines: magazines
});

在这条路线中,如果用户订阅了该杂志,我想加入订阅杂志。

在sql中,这将是一个外连接,

select *
from magazines
outer join subscriptions
  where subscriptions.magazine_id = magazine.id
    and owner_id = $current_user_id

StackOverflow上的其他问题/答案假设子模式(magazine)将_creator引用subscriber。但这不是这种情况。订阅者和杂志是他们自己的实体,他们应该没有直接参考,只能通过subscription has-many-through模型。

我如何在猫鼬中做到这一点?

1 个答案:

答案 0 :(得分:0)

这就是我认为的“天真”方法,做两个查询然后用简单的javascript加入它们。

  let magazines = await Magazine.find().lean();
  if (!magazines) return next(err);

  if (req.user) {
    let subscriptions = await Subscription.find({owner: req.user}).lean();
    let subscriptionsLookup = _.keyBy(subscriptions, 'magazine');
    magazines.forEach((magazine) => {
      if (magazine._id in subscriptionsLookup) {
        magazine.subscription = subscriptionsLookup[magazine._id];
      }
    });
  }

res.render('magazines', {
  layout: false,
  magazines: magazines
});

现在,视图可以检查用户是否已订阅杂志。

我觉得这种做法很严厉。我提交这个作为答案,因为它是 答案。我不希望这是最好的答案。这只是我到目前为止的方法。