Javascript mongoose中的内部连接2个表

Javascript mongoose中的内部连接2个表,javascript,node.js,mongoose,inner-join,lookup,Javascript,Node.js,Mongoose,Inner Join,Lookup,我试图做一个匹配的内部连接,但由于某种原因,我得到了一个左连接。 我有两个关系表,我想得到具有类型名称的电影 考虑以下模型: // Movie const MovieSchema = new mongoose.Schema({ id: { type: Number, default: null, required: true, unique: true }, title: { type: St

我试图做一个匹配的内部连接,但由于某种原因,我得到了一个左连接。 我有两个关系表,我想得到具有类型名称的电影

考虑以下模型:

// Movie
const MovieSchema = new mongoose.Schema({
    id: {
        type: Number,
        default: null,
        required: true,
        unique: true
    },
    title: {
        type: String,
        default: null,
        required: true,
        unique: true,
        trim: true
    },
});
const Movie = mongoose.model('Movie', MovieSchema);
module.exports = Movie;

// Genre
const GenreSchema = new mongoose.Schema({
    id: {
        type: Number,
        default: null,
        required: true,
        unique: true
    },
    name: {
        type: String,
        default: null,
        required: false,
        trim: true,
        unique: true
    }
});
const Genre = mongoose.model('Genre', GenreSchema);
module.exports = Genre;

// MovieGenre
const MovieGenreSchema = new mongoose.Schema({
    genreId: {
        type: Number,
        default: null,
        required: true
    },
    movieId: {
        type: Number,
        default: null,
        required: true
    }
});
const MovieGenre = mongoose.model('MovieGenre', MovieGenreSchema);
module.exports = MovieGenre;
我尝试执行以下查询:

    {
        $lookup:
        {
            from: MovieGenre.collection.name,
            localField: 'id',
            foreignField: 'movieId',
            as: 'movieGenres'
        }
    },
    {
        $lookup: {
            from: Genre.collection.name,
            localField: 'g.id',
            foreignField: 'genreId',
            as: 'genreNames'
        }
    },
    {
        $match: {
            'genreNames.name': 'Action'
        }
    }
我得到的结果是:

{
  _id: 5ee9b51609f44c0f38262c94,
  id: 26583,
  title: 'The Keeper',
  __v: 0,
  movieGenres: [
    {
      _id: 5ee8b8cf0d186c20b4bf3ccd,
      genreId: 28,
      movieId: 26583,
      __v: 0
    },
    {
      _id: 5ee8b8cf0d186c20b4bf3cce,
      genreId: 53,
      movieId: 26583,
      __v: 0
    }
  ],
  genreNames: [
    { _id: 5ee8b68f0d186c20b4b03a3d, id: 35, name: 'Comedy', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a3e, id: 80, name: 'Crime', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a40, id: 18, name: 'Drama', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a42, id: 53, name: 'Thriller', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a43, id: 28, name: 'Action', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a45, id: 14, name: 'Fantasy', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a46, id: 27, name: 'Horror', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a4a, id: 10752, name: 'War', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a4b, id: 10402, name: 'Music', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a4c, id: 37, name: 'Western', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a4d, id: 36, name: 'History', __v: 0 }
  ]
}
但我希望得到的是:

{
  _id: 5ee9b51609f44c0f38262c94,
  id: 26583,
  title: 'The Keeper',
  __v: 0,
  movieGenres: [
    {
      _id: 5ee8b8cf0d186c20b4bf3ccd,
      genreId: 28,
      movieId: 26583,
      __v: 0
    },
    {
      _id: 5ee8b8cf0d186c20b4bf3cce,
      genreId: 53,
      movieId: 26583,
      __v: 0
    }
  ],
  genreNames: [
    { _id: 5ee8b68f0d186c20b4b03a43, id: 28, name: 'Action', __v: 0 },
    { _id: 5ee8b68f0d186c20b4b03a42, id: 53, name: 'Thriller', __v: 0 },
  ]
}
你能告诉我吗, 我做错了什么?
谢谢。

您只需使用流派集更正第二次查找,我添加了两种方法,您可以使用任何人

1) 使用您的方法:
  • localField
    传递上一次查找结果的
    movieGenres.genreId
  • foreignField
    pass
    id
如果要通过
name
从上面的查找中筛选
genrename
名称

  • $filter
    迭代
    genreNames
    数组的循环,并按
    name:Action
你最后的问题是

  {
    $lookup: {
      from: MovieGenre.collection.name,
      localField: "id",
      foreignField: "movieId",
      as: "movieGenres"
    }
  },
  {
    $lookup: {
      from: Genre.collection.name,
      localField: "movieGenres.genreId",
      foreignField: "id",
      as: "genreNames"
    }
  },
  {
    $match: {
      "genreNames.name": "Action"
    }
  },
  {
    $addFields: {
      genreNames: {
        $filter: {
          input: "$genreNames",
          cond: { $eq: ["$$this.name", "Action"] }
        }
      }
    }
  }


2) 使用管道查找方法: 另一种方法是

  • 从上面的查找中传递
    movieGenres.genreId
  • $match
    使用
    $expr
    表达式匹配和
    name
    字段匹配
    genreId
    ,并使用
    $and
    操作组合条件

  {
    $addFields: {
      genreNames: {
        $filter: {
          input: "$genreNames",
          cond: { $eq: ["$$this.name", "Action"] }
        }
      }
    }
  }
  {
    $lookup: {
      from: MovieGenre.collection.name,
      localField: "id",
      foreignField: "movieId",
      as: "movieGenres"
    }
  },
  {
    $lookup: {
      from: Genre.collection.name,
      localField: "movieGenres.genreId",
      foreignField: "id",
      as: "genreNames"
    }
  },
  {
    $match: {
      "genreNames.name": "Action"
    }
  },
  {
    $addFields: {
      genreNames: {
        $filter: {
          input: "$genreNames",
          cond: { $eq: ["$$this.name", "Action"] }
        }
      }
    }
  }
  {
    $lookup: {
      from: MovieGenre.collection.name,
      localField: "id",
      foreignField: "movieId",
      as: "movieGenres"
    }
  },
  {
    $lookup: {
      from: Genre.collection.name,
      let: { genreIds: "$movieGenres.genreId" },
      pipeline: [
        {
          $match: {
            $and: [
              { $expr: { $in: ["$id", "$$genreIds"] } },
              { name: "Action" }
            ]
          }
        }
      ],
      as: "genreNames"
    }
  }