У меня есть документы, которые выглядят так:
{
{
"id": "5c4a208bbddbb7c2ae231584",
"sections": [
{
"id": "5c4a208bbddbb7c2ae231576",
"subsections": [
{
"isReviewed": true,
"flags": {
"types": [
"UNORIGINAL",
"SIMILAR"
],
"predicted": [
"UNORIGINAL",
"SIMILAR"
]
}
}
]
}
]
}
{
"id": "5c4a208bbddbb7c2ae231585",
"sections": [
{
"id": "5c4a208bbddbb7c2ae231580",
"subsections": [
{
"isReviewed": false,
"flags": {
"types": [
"SIMILAR"
],
"predicted": []
}
}
]
}
]
}
}
С этим документом я хочу вычислить статус каждого документа, используя комбинацию его поля isReviewed
и его subsections
. * 1006.*
Документом является
STATUS_REVIEWED
, если все его подразделов, которые имеют элементы в predicted
, равны isReviewed = true
STATUS_PARTIAL
, если некоторые его подразделов, которые содержат элементы в predicted
, равны isReviewed = true
STATUS_UNREVIEWED
, если все его подразделов, которые имеютэлементы в predicted
равны isReviewed = false
STATUS_IRRELEVANT
, если ни один из его подразделов не содержит элементов в predicted
Правильный результат с этими данными будет выглядеть следующим образом:
Желаемый результат
[
{
"id": "5c4a208bbddbb7c2ae231584",
// All of its subsections are reviewed and has items in predicted
"reviewStatus": ["STATUS_REVIEWED"]
},
"id": "5c4a208bbddbb7c2ae231585",
// All of its subsections do not have any items in predicted
"reviewStatus": ["STATUS_IRRELEVANT"]
},
]
В настоящее время у меня есть запрос агрегации, который работает, но требует, чтобы я выполнил некоторую постобработку с JavaScript, чтобы компенсировать документы, которые не возвращаются.
Item.aggregate()
.match({ _id: { $in: ids } })
.project({ a: '$sections.subsections' })
.unwind('$a')
.unwind('$a')
.project({
isReviewed: '$a.isReviewed',
hasPredictions: { $gt: [{ $size: '$a.flags.predicted' }, 0] }
})
.match({ hasPredictions: true })
.group({ _id: '$_id', reviewStatuses: { $addToSet: '$isReviewed' } })
.group({
_id: '$_id',
reviewStatus: {
$push: {
$switch: {
branches: [
{
case: {
$and: [
{ $in: [false, '$reviewStatuses'] },
{ $in: [true, '$reviewStatuses'] },
]
},
then: 'STATUS_PARTIAL'
},
{
case: {
$eq: [[true], '$reviewStatuses']
},
then: 'STATUS_REVIEWED'
},
{
case: {
$eq: [[false], '$reviewStatuses']
},
then: 'STATUS_UNREVIEWED'
}
],
default: 'STATUS_UNKNOWN'
}
}
}
})
// Post processing
.then((items) => {
const itemsById = _.keyBy(items, '_id');
return itemIds.map((itemId) => {
const status = itemsById[itemId];
// Set to STATUS_IRRELEVANT item is not in result
if (status === undefined) return 'STATUS_IRRELEVANT';
return status.reviewStatus[0];
});
})
Этот запрос прекрасно работает, но если в документе нет подразделов с элементами в predicted
, шаг сопоставления будет пропущендокумент из результата и потребует от меня последующей обработки, чтобы проверить, есть ли документ в результате (а затем добавить 'STATUS_IRRELEVANT').
Что я получу
[
{
"id": "5c4a208bbddbb7c2ae231584",
// All of its subsections are reviewed and items in predicted
"reviewStatus": ["STATUS_REVIEWED"]
}
// Doc "5c4a208bbddbb7c2ae231585" is missing here because of the match
]
Как мне переписать этот запрос, чтобы получить желаемый результат?