MongoDB assymetrical return of data, first item in array returned in full, the rest with certain properties omitted?

回眸只為那壹抹淺笑 提交于 2020-07-10 10:23:44

问题


I'm new to MongoDB and getting to grips with its syntax and capabilities. To achieve the functionality described in the title I believe I can create a promise that will run 2 simultaneous queries on the document - one to get the full content of one item in the array (or at least the data that is omitted in the other query, to re-add after), searched for by most recent date, the other to return the array minus specific properties. I have the following document:

{ 
  _id : ObjectId('5rtgwr6gsrtbsr6hsfbsr6bdrfyb'),
  uuid : 'something',
  mainArray : [
      {
          id : 1,
          title: 'A',
          date: 05/06/2020,
          array: ['lots','off','stuff']
      },
      {
          id : 2,
          title: 'B',
          date: 28/05/2020,
          array: ['even','more','stuff']
      },
      {
          id : 3,
          title: 'C',
          date: 27/05/2020,
          array: ['mountains','of','knowledge']
      }
  ]
}

and I would like to return

{ 
  uuid : 'something',
  mainArray : [
      {
          id : 1,
          title: 'A',
          date: 05/06/2020,
          array: ['lots','off','stuff']
      },
      {
          id : 2,
          title: 'B'
      },
      {
          id : 3,
          title: 'C'
      }
  ]
}

How valid and performant is the promise approach versus constructing one query that would achieve this? I have no idea how to perform such 'combined-rule'/conditions in MongoDB, if anyone could give an example?


回答1:


If your subdocument array you want to omit is not very large. I would just remove it at the application side. Doing processing in MongoDB means you choose to use the compute resources of MongoDB instead of your application. Generally your application is easier and cheaper to scale, so implementation at the application layer is preferable.

But in this exact case it's not too complex to implement it in MongoDB:

db.collection.aggregate([
  {
    $addFields: { // keep the first element somewhere
      first: { $arrayElemAt: [ "$mainArray", 0] }
    }
  },
  {
    $project: { // remove the subdocument field
      "mainArray.array": false
    }
  },
  {
    $addFields: { // join the first element with the rest of the transformed array
      mainArray: {
        $concatArrays: [
          [ // first element
            "$first"
          ],
          { // select elements from the transformed array except the first
            $slice: ["$mainArray", 1, { $size: "$mainArray" }]
          }
        ]
      }
    }
  },
  {
    $project: { // remove the temporary first elemnt
      "first": false
    }
  }
])

MongoDB Playground



来源:https://stackoverflow.com/questions/62386313/mongodb-assymetrical-return-of-data-first-item-in-array-returned-in-full-the-r

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!