MongoDB故意只返回没有匹配$lookup结果的用户

MongoDB故意只返回没有匹配$lookup结果的用户,mongodb,mongoose,Mongodb,Mongoose,我有一个用户模式和一个投票模式。我试图只返回未投票的用户(没有返回的投票) 我找到并使用下面的代码找到每个用户并返回他们的所有投票。这是我努力实现的一半 我如何构建一个查询,使其仅在用户没有投票权时返回用户 db.users.aggregate([ { $addFields: { "_id": { "$toString": "$_id" } } }, { $lookup:

我有一个
用户
模式和一个
投票
模式。我试图只返回未投票的用户(没有返回的投票)

我找到并使用下面的代码找到每个用户并返回他们的所有投票。这是我努力实现的一半

我如何构建一个查询,使其仅在用户没有投票权时返回用户

db.users.aggregate([
    { 
        $addFields: { "_id": { "$toString": "$_id" } }
    },
   {
     $lookup:
       {
         from: "votes",
         localField: "_id",
         foreignField: "voterId",
         as: "votes"
       }
  }
])
另一个问题是,一旦我有了一个有效的解决方案,我将如何扩大规模?在Robo3T中运行此查询只需加载50个用户就需要9.05秒,我的数据库中有近40000个用户和200000多张投票(只会增加)。有没有更有效的方法?最后的代码将在Node.js服务器上运行

更新 正如在删除的回答中所说,我不需要使用
$addFields
,因为
user.\u id
会自动转换为字符串(我最初认为它是
ObjectId()
)。但是,这只节省了加载50个用户的1秒时间(8.14秒)


我仍然需要弄清楚如何只返回那些没有投票的用户。

您的数据示例和预期结果会有所帮助。
$addFields
函数很可能是影响性能的因素。你为什么需要这个

如果投票人集合中的
voterId
格式为字符串,而用户集合中的
objectId
格式为字符串(我猜是这样),那么如果您想要获得最大性能,您需要永久转换为
objectId
。尽管如此,这大致就是您要寻找的:

db.users.aggregate([
{
 $lookup:
   {
     from: "votes",
     localField: "_id",
     foreignField: "voterId",
     as: "votes"
   }
 },
 { "$match": { "votes.0": { "$exists": false } } }
])
仅此操作将仅返回没有投票条目的用户。本质上相当于左连接

更新
因为它们都是字符串,所以您可以忽略答案的这一方面。至于你的表现问题。。。目前还不确定。这似乎很不现实,,通过简单的$lookup,我从未经历过如此漫长的查询时间。

请在jsoneditor上共享请求数据和响应数据online@MaheshBhatnagar唯一重要的字段是
user.\u id
voces.voterId
,这两个字段都是字符串,如果找到了投票,它们应该匹配。我发现这只保存了你只需要一秒钟。。。我得考虑一下。无论如何,我会同时更新我的答案。8.14s完全不可接受!我确认这个答案是感谢@silencedogood,这个解决方案有效。我将尝试并可能将这两个模式拉入本地的两个JSON文件中,在JS中进行比较,看看是否可以加快速度。或者我可以试着在本地运行DB,这可能就是它花费这么长时间的原因。@LukeBrown没问题。我认为在本地运行是个好主意,只是为了帮助隔离性能问题。同时,我正在研究查询是否存在固有的性能问题。如果是这样的话,我可能会想出其他方法来实现这一点。结果是更好的性能,但是,我不太确定,我必须看看。如果您有一秒钟的时间,请标记为“解决方案”。@SilencedGood导出用户和投票并在本地运行查询会将50个用户的时间从9秒减少到2秒。所有用户运行的时间从118分钟减少到现在的26分钟。我会继续努力。事后看来,我应该在用户投票后建立一个权限,名为
hasvoite
,然后我可以查询所有没有这个值的用户——这会快得多,但我不再有这个选项了。@LukeBrown我的想法:)
db.users.aggregate([
{
 $lookup:
   {
     from: "votes",
     localField: "_id",
     foreignField: "voterId",
     as: "votes"
   }
 },
 { "$match": { "votes.0": { "$exists": false } } }
])