MongoDB通过$ in运算符聚合

时间:2019-07-08 06:14:00

标签: mongodb

帖子

> db.posts.find()
{ "_id" : ObjectId("5d22de26fc60aab610f73e04"), "post_id" : 1, "user_id" : 1, "body" : "first", "is_block" : false }
{ "_id" : ObjectId("5d22de26fc60aab610f73e05"), "post_id" : 2, "user_id" : 1, "body" : "second", "is_block" : false }
{ "_id" : ObjectId("5d22de26fc60aab610f73e06"), "post_id" : 3, "user_id" : 2, "body" : "third", "is_block" : false }
{ "_id" : ObjectId("5d22de26fc60aab610f73e07"), "post_id" : 4, "user_id" : 3, "body" : "lalala", "is_block" : false }
{ "_id" : ObjectId("5d22de26fc60aab610f73e08"), "post_id" : 5, "user_id" : 4, "body" : "gogo", "is_block" : false }
{ "_id" : ObjectId("5d22de27fc60aab610f73e09"), "post_id" : 6, "user_id" : 5, "body" : "gogo", "is_block" : true }

关系

> db.relationships.find()
{ "_id" : ObjectId("5d22dd19fc60aab610f73e02"), "user_id" : 1, "target_user_id" : 2 }
{ "_id" : ObjectId("5d22dd1cfc60aab610f73e03"), "user_id" : 1, "target_user_id" : 3 }

我想找到满足以下条件的posts

  1. user_idrelationships

  2. 不关联
  3. postsis_block = false

  4. posts不是自己写的

如果观看者user_id1,则预期结果是

{ "_id" : ObjectId("5d22de26fc60aab610f73e08"), "post_id" : 5, "user_id" : 4, "body" : "gogo", "is_block" : false }

post_id = 1是自写帖子

post_id = 2是自写帖子

post_id = 3relationships

相关联

post_id = 4relationships

相关联

post_id = 6is_block = true

与下面的mysql查询等效。

SELECT posts.* FROM posts
WHERE posts.user_id NOT IN
(
SELECT target_user_id FROM relationships WHERE user_id=1
)

如何通过汇总提取预期结果?

在mongodb上可以吗?

谢谢。

3 个答案:

答案 0 :(得分:1)

您可以使用以下聚合:

db.getCollection('posts').aggregate([{
    $match : {
        is_block : false,
        user_id : {$ne : 1}
    }
},{
    $lookup : {
        from : "relationships",
        as : "related",
        localField : "user_id",
        foreignField : "target_user_id"
    }
},{
    $match : {
        "related.user_id" : {$ne  : 1}
    }
}])

答案 1 :(得分:0)

一个简单的聚合就足够了:

db.collection.aggregate([
    {
       $match: {
           $and: [
             { is_block: false},
             {"post_id" {$ne: "$user_id"}}
           ]
       }
    },
    {
        $lookup: {
            from: "relationships",
            localField: "user_id",
            foreignField: "target_user_id",
            as: "match"
        }
    },
    {
       $match: {
          "match.0": {$exists: false}
       }
    }
])

答案 2 :(得分:0)

基本上,您要尝试的是将一个查询的结果用于另一个查询。 MongoDB专为平面文档而设计,紧密构建的关系需要仔细构建,或者尽可能避免。

您可以做的是,在您的程序中运行两个查询,因为使用索引的简单查询将比聚合更快。

target_user_id表中获取relationships

var relatedUserIds = [1];    // since viewers user_id is 1
db.relationships.find({"user_id" : 1}).forEach(function(i) { relatedUserIds.push(i.target_user_id); })

在具有posts集合的查找查询中使用结果数组:

db.posts.find({ 
    user_id : { $nin: relatedUserIds},
    is_block: false
    });

这将为您提供以下结果:

{
    "_id" : ObjectId("5d22de26fc60aab610f73e08"),
    "post_id" : 5,
    "user_id" : 4,
    "body" : "gogo",
    "is_block" : false
}
  

要对此使用大量记录,请在   relationships.userIdposts.userIdpost.isBlock提高速度   结果。

希望这会有所帮助。