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\$
1
  • \$\begingroup\$ IIIUC you are running the query against the same collection \$\endgroup\$
    – Sede
    Mar 4, 2017 at 17:37

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.