2
\$\begingroup\$

Here is a code block I have:

const _ = require('lodash')
const Box = require('./models/Box')

const boxesToBePicked = await Box.find({ status: 'ready' })
const boxesOriginalIds = _(boxesToBePicked).map('original').compact().uniq().value()
const boxesOriginal = boxesOriginalIds.length ? await Box.find({ _id: { $in: boxesOriginalIds } }) : []

const attributes = ['name']

const boxes = [
  ...boxesOriginal,
  ...boxesToBePicked.filter(box => !box.original)
].map(box => _.pick(box, attributes))

Let's say, we have following data in the "boxes" collection:

[
  { _id: 1, name: 'Original Box #1', status: 'pending' },
  { _id: 2, name: 'Nested box', status: 'ready', original: 1 },
  { _id: 3, name: 'Nested box', status: 'ready', original: 1 },
  { _id: 4, name: 'Nested box', status: 'pending', original: 1 },
  { _id: 5, name: 'Original Box #2', status: 'ready' },
  { _id: 6, name: 'Original Box #3', status: 'pending' },
  { _id: 7, name: 'Nested box', status: 'ready', original: 6 },
  { _id: 8, name: 'Original Box #4', status: 'pending' }
]

Workflow

Find all boxes, which are ready to be picked:

const boxesToBePicked = await Box.find({ status: 'ready' })

// Returns:

[
  { _id: 2, name: 'Nested box', status: 'ready', original: 1 },
  { _id: 3, name: 'Nested box', status: 'ready', original: 1 },
  { _id: 5, name: 'Original Box #2', status: 'ready' },
  { _id: 7, name: 'Nested box', status: 'ready', original: 6 }
]

Get all the IDs of the original (parent) boxes of those:

const boxesOriginalIds = _(boxesToBePicked).map('original').compact().uniq().value()

// Returns:

[1, 6]

Get those boxes by their IDs:

const boxesOriginal = boxesOriginalIds.length ? await Box.find({ _id: { $in: boxesOriginalIds } }) : []

// Returns

[
  { _id: 1, name: 'Original Box #1', status: 'pending' },
  { _id: 6, name: 'Original Box #3', status: 'pending' }
]

Join those boxes with non-nested boxes to be picked:

const boxes = [
  ...boxesOriginal,
  ...boxesToBePicked.filter(box => !box.original)
].map(box => _.pick(box, attributes))

// Returns

[
  { name: 'Original Box #1' },
  { name: 'Original Box #3' },
  { name: 'Original Box #2' }
]

So basically what we are doing here is getting all the original boxes if they have at least one nested box with status "ready", and all non-nested boxes with status "ready".

I think it can be simplified by using aggregation pipeline and projection. But how does one do that?

\$\endgroup\$
  • \$\begingroup\$ IIIUC you are running the query against the same collection \$\endgroup\$ – styvane Mar 4 '17 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.