如何向mongodb查找添加ObjectId参数

如何向mongodb查找添加ObjectId参数,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我正在进行查找,其中本地字段是ObjectId,外部字段是ObjectId的数组。执行查找时会出现以下错误: arguments to $lookup must be strings 我做过类似的查找,其中外部字段不是数组(而是ObjectId),因此错误似乎不明确。我的数据库由两个集合组成:歌曲和播放列表。一首歌可以属于多个播放列表。我正在尝试编写一个聚合,该聚合返回一首匹配的歌曲,其中包含该歌曲所属的播放列表数组: 歌曲: [ { songName: "In Da Club",

我正在进行查找,其中本地字段是ObjectId,外部字段是ObjectId的数组。执行查找时会出现以下错误:

arguments to $lookup must be strings
我做过类似的查找,其中外部字段不是数组(而是ObjectId),因此错误似乎不明确。我的数据库由两个集合组成:歌曲和播放列表。一首歌可以属于多个播放列表。我正在尝试编写一个聚合,该聚合返回一首匹配的歌曲,其中包含该歌曲所属的播放列表数组:

歌曲:

[
  {
    songName: "In Da Club",
    _id: ObjectId(1)
  },
  {
    songName: "Happy Birthday",
    _id: ObjectId(2)
  },
  {
    songName: "Ode to Joy",
    _id: ObjectId(3)
  }
]


[
  {
    _id: ObjectId(4)
    playlistName: "PlaylistOne,
    songs: [ObjectId(1), ObjectId(3)]
  },
  {
    _id: ObjectId(5)
    playlistName: "PlaylistTwo,
    songs: [ObjectId(1)]
  }
]


{
  songName: "In Da Club",
  _id: ObjectId(1),
  playlists: [
    {
      _id: ObjectId(4),
      playlistName: "PlaylistOne,
    },
    {
      _id: ObjectId(5),
      playlistName: "PlaylistTwo"
    }
  ]
}



db.songs.aggregate([
  {
    $match: {
      songName: "In Da Club"
    }
  },
  {
    $lookup: {
      from: 'playlists',
      let: { songId: '$_id'},
      pipeline: [
        {
          $match: {
            $expr: {
              {
                $in: ["$$songId", "$songs"]
              }
            }
          }
        }
      ],
      as: 'playlists'
    }
  }
])
播放列表:

[
  {
    songName: "In Da Club",
    _id: ObjectId(1)
  },
  {
    songName: "Happy Birthday",
    _id: ObjectId(2)
  },
  {
    songName: "Ode to Joy",
    _id: ObjectId(3)
  }
]


[
  {
    _id: ObjectId(4)
    playlistName: "PlaylistOne,
    songs: [ObjectId(1), ObjectId(3)]
  },
  {
    _id: ObjectId(5)
    playlistName: "PlaylistTwo,
    songs: [ObjectId(1)]
  }
]


{
  songName: "In Da Club",
  _id: ObjectId(1),
  playlists: [
    {
      _id: ObjectId(4),
      playlistName: "PlaylistOne,
    },
    {
      _id: ObjectId(5),
      playlistName: "PlaylistTwo"
    }
  ]
}



db.songs.aggregate([
  {
    $match: {
      songName: "In Da Club"
    }
  },
  {
    $lookup: {
      from: 'playlists',
      let: { songId: '$_id'},
      pipeline: [
        {
          $match: {
            $expr: {
              {
                $in: ["$$songId", "$songs"]
              }
            }
          }
        }
      ],
      as: 'playlists'
    }
  }
])
期望的结果:

[
  {
    songName: "In Da Club",
    _id: ObjectId(1)
  },
  {
    songName: "Happy Birthday",
    _id: ObjectId(2)
  },
  {
    songName: "Ode to Joy",
    _id: ObjectId(3)
  }
]


[
  {
    _id: ObjectId(4)
    playlistName: "PlaylistOne,
    songs: [ObjectId(1), ObjectId(3)]
  },
  {
    _id: ObjectId(5)
    playlistName: "PlaylistTwo,
    songs: [ObjectId(1)]
  }
]


{
  songName: "In Da Club",
  _id: ObjectId(1),
  playlists: [
    {
      _id: ObjectId(4),
      playlistName: "PlaylistOne,
    },
    {
      _id: ObjectId(5),
      playlistName: "PlaylistTwo"
    }
  ]
}



db.songs.aggregate([
  {
    $match: {
      songName: "In Da Club"
    }
  },
  {
    $lookup: {
      from: 'playlists',
      let: { songId: '$_id'},
      pipeline: [
        {
          $match: {
            $expr: {
              {
                $in: ["$$songId", "$songs"]
              }
            }
          }
        }
      ],
      as: 'playlists'
    }
  }
])
我尝试的查询:

[
  {
    songName: "In Da Club",
    _id: ObjectId(1)
  },
  {
    songName: "Happy Birthday",
    _id: ObjectId(2)
  },
  {
    songName: "Ode to Joy",
    _id: ObjectId(3)
  }
]


[
  {
    _id: ObjectId(4)
    playlistName: "PlaylistOne,
    songs: [ObjectId(1), ObjectId(3)]
  },
  {
    _id: ObjectId(5)
    playlistName: "PlaylistTwo,
    songs: [ObjectId(1)]
  }
]


{
  songName: "In Da Club",
  _id: ObjectId(1),
  playlists: [
    {
      _id: ObjectId(4),
      playlistName: "PlaylistOne,
    },
    {
      _id: ObjectId(5),
      playlistName: "PlaylistTwo"
    }
  ]
}



db.songs.aggregate([
  {
    $match: {
      songName: "In Da Club"
    }
  },
  {
    $lookup: {
      from: 'playlists',
      let: { songId: '$_id'},
      pipeline: [
        {
          $match: {
            $expr: {
              {
                $in: ["$$songId", "$songs"]
              }
            }
          }
        }
      ],
      as: 'playlists'
    }
  }
])
这似乎是一个相对简单的查询,我不确定如何绕过“传入查找的参数必须是字符串”错误,因为我的查找是基于ObjectId的。任何帮助都将不胜感激!蒂亚

虽然在版本
3.2
中引入,但在后续更新中对其进行了几项增强:

根据文件:

[
  {
    songName: "In Da Club",
    _id: ObjectId(1)
  },
  {
    songName: "Happy Birthday",
    _id: ObjectId(2)
  },
  {
    songName: "Ode to Joy",
    _id: ObjectId(3)
  }
]


[
  {
    _id: ObjectId(4)
    playlistName: "PlaylistOne,
    songs: [ObjectId(1), ObjectId(3)]
  },
  {
    _id: ObjectId(5)
    playlistName: "PlaylistTwo,
    songs: [ObjectId(1)]
  }
]


{
  songName: "In Da Club",
  _id: ObjectId(1),
  playlists: [
    {
      _id: ObjectId(4),
      playlistName: "PlaylistOne,
    },
    {
      _id: ObjectId(5),
      playlistName: "PlaylistTwo"
    }
  ]
}



db.songs.aggregate([
  {
    $match: {
      songName: "In Da Club"
    }
  },
  {
    $lookup: {
      from: 'playlists',
      let: { songId: '$_id'},
      pipeline: [
        {
          $match: {
            $expr: {
              {
                $in: ["$$songId", "$songs"]
              }
            }
          }
        }
      ],
      as: 'playlists'
    }
  }
])
在启动MongoDB 3.4时,如果localField是一个数组,则可以匹配 针对标量外来字段的数组元素,而不需要 $unwind阶段

MongoDB 3.6增加了对在连接的服务器上执行管道的支持 集合,它允许将多个联接条件指定为 以及不相关的子查询

所以问题可能是mongodb版本太低。无论如何,根据您的要求,您可以使用
$lookup
,它用于单个相等联接,因为数组位于
foreignField

{
    $lookup: {
      from: "playlists",
      localField: "_id", // Scalar value
      foreignField: "songs", // Against an array
      as: "playlists"
    }
  }

测试:

除了查询中的两个语法错误之外,一切看起来都很好,在这里测试:,您的MongoDB版本是什么?它托管在哪里?啊,好的-我在本地运行MongoDB版本3.6。。。我将升级到最新版本,然后重试。谢谢我在3.2***上尝试一下:&让我知道!你可能会遇到同样的问题,但请告诉我会发生什么……啊,这也行!我甚至没有尝试,因为我认为它不会工作,因为外场是一个数组。。。非常感谢!