使用其文档聚合填充ID数组

时间:2017-06-28 07:35:26

标签: mongodb mongodb-query aggregation-framework

我在mongodb中使用了一些聚合函数。 我想获取书籍作者文档中的文档,其中只有书籍ID作为字符串数组,如下所示:

作者文件

{
  "_id" : "10",
  "full_name" : "Joi Dark",
  "books" : ["100", "200", "351"],
}

和其他文件(书籍):

{
    "_id" : "100",
    "title" : "Node.js In Action",
    "ISBN" : "121215151515154",
    "date" : "2015-10-10"
}

所以结果我想要这个:

{
  "_id" : "10",
  "full_name" : "Joi Dark",
  "books" : [
       {
           "_id" : "100",
           "title" : "Node.js In Action",
           "ISBN" : "121215151515154",
           "date" : "2015-10-10"
       },
       {
           "_id" : "200",
           "title" : "Book 2",
           "ISBN" : "1212151454515154",
           "date" : "2015-10-20"
       },
       {
           "_id" : "351",
           "title" : "Book 3",
           "ISBN" : "1212151454515154",
           "date" : "2015-11-20"
       }
  ],
}

1 个答案:

答案 0 :(得分:2)

使用$lookup根据fromlocalField的匹配来检索foreignField中指定馆藏的数据:

db.authors.aggregate([
  { "$lookup": {
    "from": "$books",
    "foreignField": "_id",
    "localField": "books",
    "as": "books"
  }}
])

as是文档中编写"数组"的位置。包含相关文件。如果指定现有属性(例如此处完成),则该属性将被输出中的新数组内容覆盖。

如果您在MongoDB 3.4之前有MongoDB,那么您可能需要"books" localField数组作为db.authors.aggregate([ { "$unwind": "$books" }, { "$lookup": { "from": "$books", "foreignField": "_id", "localField": "books", "as": "books" }} ]) 首先:

db.authors.aggregate([
  { "$unwind": "$books" },
  { "$lookup": {
    "from": "$books",
    "foreignField": "_id",
    "localField": "books",
    "as": "books"
  }},
  { "$unwind": "$books" },
  { "$group": {
    "_id": "$_id",
    "full_name": { "$first" "$full_name" },
    "books": { "$push": "$books" }
  }}
])

为原始文档中的每个数组成员创建一个新文档,因此再次使用$unwind$unwind创建原始表单:

_id

实际上,如果ObjectId类型的外国集合中的localField值,但var ops = []; db.authors.find().forEach(doc => { doc.books = doc.books.map( book => new ObjectId(book.valueOf()) ); ops.push({ "updateOne": { "filter": { "_id": doc._id }, "update": { "$set": { "books": doc.books } } } }); if ( ops.length >= 500 ) { db.authors.bulkWrite(ops); ops = []; } }); if ( ops.length > 0 ) { db.authors.bulkWrite(ops); ops = []; } 中的值为"字符串"那个版本,然后你需要转换数据,以便类型匹配。没有其他办法。

通过shell运行类似的东西进行转换:

"books"

这会将ObjectId数组中的所有值转换为可在$lookup操作中实际匹配的实际{{1}}值。