使用NodeJS的MongoDB复杂$ graphlookup

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (273)

我正在写一个NodeJS程序,我已经打了一个mongo墙。我是编写复杂的MongoDB查询的新手,根据我的知识,MongoDB的NodeJS实现还没有包含'createView()'函数,这更具挑战性。这是我的数据库的结构与示例数据:

-------------------------------
_id | username | friends(array)
-------------------------------
  1 |   user1  |    [user2]
  2 |   user2  | [user1, user3]
  3 |   user4  |    [user3]

我正在尝试编写一个查询,检查user1的朋友中的任何朋友是否等于user2的朋友。(在这种情况下,我只想返回一个只包含'user3'的数组)

由于无法使用视图并且必须使用单个包含的查询来执行所有这些逻辑,因此我在使用此问题进行任何进展时遇到了一些困难。我知道mongo有一些函数,比如$ graphlookup,它可能对解决方案有用,但我无处可用。

如果有人有兴趣,这是我到目前为止所得到的:

// Query1 this creates a view that 
// contains all usernames of friends of user4

db.createView(
  'userView',
  collection, [{
    $match: {
      username: user4
    }
  }, {
    $unwind: "$friends"
  }, {
    $group: {
      _id: "$friends"
    }
  }, {
    $project: {
      _id: 1
    }
  }]
);

.

// Query2 this creates a view that
// contains all usernames of friends of friends of user1

db.createView(
  'friendsView',
  collection, [{
    $match: {
      username: {
        $in: user1FriendsArray
      }
    }
  }, {
    $unwind: "$friends"
  }, {
    $group: {
      _id: "$friends"
    }
  }, {
    $project: {
      _id: 1
    }
  }]
);

.

// Query3 (this is incorrect) this query should find 
// any matches between the two views and return them within an array

db.collection.aggregate([{
  $group: {
    _id: {
      $and: [userView.$_id, friendsView.$_id]
    },
    count: {
      $sum: 1
    }
  }
}, {
  $match: {
    count: 2
  }
}, {
  $project: {
    _id: 1
  }
}]);

我相信会有一种方法可以执行所有这一个单一的查询,但是我总是在制定一个可能是查询的噩梦。

非常感谢任何帮助<3

提问于
用户回答回答于

聚合投影阶段的$ setIntersection

db.getCollection('my_users_collection').aggregate([
// get user1
{$match: { username: 'user1'}},
// get user1's friend with username of 'user2'
{$graphLookup: {
    from: 'my_users_collection',
    startWith: '$friends',
    connectFromField: 'friends',
    connectToField: 'username',
    as: 'foundFriend',
    maxDepth: 0,
    restrictSearchWithMatch: { username: 'user2' }
}},
{$unwind: '$foundFriend'},
// only return the overlap of friends between user1 and user2
{$project: { commonFriends: { $setIntersection: ['$friends', '$foundFriend.friends']}, _id: 0 }}
])

扫码关注云+社区

领取腾讯云代金券