猫鼬内心加入

时间:2016-01-08 17:32:39

标签: node.js mongodb mongoose

用户集合

user : {
"_id" : md5random,
"nickname" : "j1",
"name" : "jany"
}
user : {
"_id" : md5random,
 "nickname" : "j2",
"name" : "jenneffer"
}

友谊收藏

friendship : {
  "_id"  : md5rand,
  "nick1" : "j1",
  "nick2"  : "j2",
  "adTime" : date
}

例如SQL

SELECT friendship.adTime, user.name 
         FROM friendship
INNER JOIN user  ON 
        (user.nickname=friendship.nick1 or user.nickname=friendship.nick2)

MONGO中有没有办法获得这个SQL结果?

我想获得结果,我知道mongo不支持这个请求。 但这个更好的解决方案是什么?任何人都可以为我写一个例子吗?

2 个答案:

答案 0 :(得分:8)

MongoDB是面向文档的,而不是关系数据库。所以它没有像sql这样的查询语言。因此,您应该更改数据库架构。

这是一个例子:

  1. 定义架构。你不能像在sql数据库中那样在mongodb中保存关系。所以直接将朋友添加到用户。要为这些关系添加属性,您必须创建一个新模型(此处:Friend)。

    var userSchema = mongoose.Schema({
        nickname: String,
        name: String,
        friends: [{type: mongoose.Schema.Types.ObjectId, ref: 'Friend'}]
    });
    
    var friendSchema = mongoose.Schema({
        user: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
        addTime: Date
    });
    
    var User = mongoose.Model('User', userSchema);
    var Friend = mongoose.Model('Friend', friendSchema);
    
  2. 您获取所有addTimes的查询可能如下所示:

    User.find().populate('friends').exec(function(err, users) {
        if (err) throw err;
    
        var adTimes = [];
        users.forEach(function(user) {
            user.friends.forEach(function(friend) {
                adTimes.push(friend.adTime);
            });
        });
    
        response.send(adTimes); // adTimes should contain all addTimes from his friends
    });
    

    注意:上述模式应该可以使用,但是您可能应该使用关系(如MySQL)或图形数据库(如Neo4j)而不是像MongoDB这样的文档。

答案 1 :(得分:2)

使用$lookup,对同一数据库中的未整数集合执行左外连接,以过滤“已连接”集合中的文档进行处理。 $ lookup阶段在输入文档中的字段与“已连接”集合的文档中的字段之间进行相等匹配。

对于每个输入文档,$ lookup阶段添加一个新的数组字段,其元素是来自“已连接”集合的匹配文档。 $ lookup阶段将这些重新整形的文档传递到下一阶段。

有关详情,请点击$lookup documentation