MongoDB:聚合查询匹配子文档数组的多个条件

时间:2020-05-12 16:11:27

标签: javascript node.js mongodb

我有一个名为Engineer的集合,其中有一个文档:

{
  id : *some mongodb id*,
  username : "xyz",
  email id : "xyz@gmail.com"
  profession : [
      {
      id : *some mongodb id* ,
      location : "Moscow",
      licence : "civil engineer"
      }
      {
      id : *some mongodb id* ,
      location : "Berlin",
      licence : "cs engineer"
      }
]
}

我有一个包含三个文档的项目集合:

{   
        "_id":"5ebaa72c9ad5010017a2179b"
        "projectName":"test project 1", 
        "status": "open"
        "licence":"cs engineer",
        "location":"Berlin",
        "description":"This is project",
        "duration":20,
 } ,
{   
        "_id":"5ebaa72c9ad5010017a2178b"
        "projectName":"test project 2",
        "status": "open"
        "licence":"civil engineer",
        "location":"Berlin",
        "description":"This is project",
        "duration":10,
 } ,
{   
        "_id":"5ebaa72c9ad5010017a2177b"
        "projectName":"test project 3",
        "status": "open"
        "licence":"civil engineer",
        "location":"Moscow",
        "description":"This is project",
        "duration":30,
 }

我有一个“出价”模式。该模式如下所示:(在工程师投标项目时存储必要的数据)

{
    "projectID": : "*some project _id"       // will be a project id
    "bids": [{
        "bidAmount":
        "engineerID": 
    }]
    "__v": 1
}

我的问题: 我只想填充工程师未出价的那些项目,并且我想将工程师的位置和许可证与该项目的位置和许可证相匹配,以便他可以查看有关他的执照和位置。因此,如果您采用上述示例数据,我只希望我的结果包含“ 测试项目1 ”和“ 测试项目3 ”的详细信息。

很抱歉,冗长的解释仅是希望人们在阅读时能够理解。 感谢任何帮助。 谢谢!!

更新:

我尝试使用此聚合查询:

// match.location = ['Moscow' , 'Berlin']
// match.licence = ['civil engineer' , 'cs engineer']

const project = await BidHistory.aggregate([
  {
    $match: {
      'bids.engineerID': { $ne: mongoose.Types.ObjectId(req.engineer.id) }
    }
  },
  {
    $lookup: {
      from: 'projects',
      localField: 'projectID',
      foreignField: '_id',
      as: 'project'
    }
  },
  {
    $match: {       
          'project.location': { $in: match.location },
          'project.licence': { $in: match.licence }
    }
  },
  {
    $project: {
      bids: 0,
      projectID: 0,
      _id: 0,
    }
  }
]);

但是通过上面的查询,我得到了不必要的数据。如果将此查询应用于我的样本数据。我也返回了我不想要的结果测试项目2 。我知道它的原因是$ in运算符,但我找不到解决方法!

注意:工程师也只能拥有一个位置和许可证

1 个答案:

答案 0 :(得分:0)

据我了解,您无法将locationlicence分开,否则它们将像您尝试的那样独立匹配。

相反,您应该将它们成对放置,这里的关键是使用$elemMatch

// note that id's are not included
const professions = [
  {
    location: "Moscow",
    licence: "civil engineer"
  },
  {
    location: "Berlin",
    licence: "cs engineer"
  }
]

然后您可以使用以下查询

const projects = BidHistory.aggregate([{
  {
    $match: {
      'bids.engineerID': { $ne: mongoose.Types.ObjectId(req.engineer.id) }
    }
  },
  {
    $lookup: {
      from: "projects",
      localField: "projectID",
      foreignField: "_id",
      as: "project"
    }
  },
  {
    $match: {
      "project": {
        $elemMatch: {
          $or: professions // use matching professions here
        }
      }
    }
  },
/* Bonus: to get projects at top level add following stages */
  {
    $unwind: '$project'
  },
  {
    $replaceRoot: { newRoot: '$project' }
  }
}])

相关问题