Вам нужно использовать aggregation-pipeline для этого:
1. Если ваш "contents.paragraphCleanText"
уникален:
Запрос:
db.collection.aggregate([
/** Filter docs based on condition */
{ $match: { "contents.paragraphCleanText": "cleaned content 3" } },
{
$project: {
_id: 0,
chapterNumber: 1,
/** contents will be an object, which is matched object, as `$filter` will return an array of matched objects, we're picking first object - assuming `contents.paragraphCleanText` is unique,
* Just in case if you've multiple objects that matches with given condition use `$reduce` instead of `$filter + $arrayElemAt` */
contents: {
$arrayElemAt: [
{ $filter: { input: "$contents", cond: { $eq: [ "$$this.paragraphCleanText", "cleaned content 3" ] } } },
0
]
}
}
},
{
$project: {
chapterNumber: 1,
paragraphNumber: "$contents.paragraphNumber",
paragraphCleanText: "$contents.paragraphCleanText"
}
}
])
Тест: mongoplayground
Примечание: Если вы хотите, чтобы весь объект из массива contents
соответствовал условию тогда вы можете просто использовать $ elemmatch-projection-operator или $ - positional-projection-operator , но поскольку вам не нужен весь объект и только несколько полей из сопоставленных объект, то вам нужно использовать параметр агрегации projection
в .find()
не может преобразовывать поля - он способен только включать или исключать поля из документа, поэтому для этого вы будете использовать этап агрегации $project
.
Если ваш
"contents.paragraphCleanText"
может иметь дубликаты, т.е. внутри массива
contents
может быть несколько объектов с
"contents.paragraphCleanText": "cleaned content 3"
:
Запрос:
db.collection.aggregate([
{ $match: { "contents.paragraphCleanText": "cleaned content 3" } },
{
$project: {
_id: 0,
chapterNumber: 1,
contents: {
$reduce: {
input: "$contents",
initialValue: [], // create an empty array to start with
in: {
$cond: [
{
$eq: [ "$$this.paragraphCleanText", "cleaned content 3" ] // Condition to check
},
{ // If an object has matched with condition concatinate array converted that object into holding array
$concatArrays: [ "$$value", [ { paragraphCleanText: "$$this.paragraphCleanText", paragraphNumber: "$$this.paragraphNumber" } ] ]
},
"$$value" // If current object is not matched return holding array as is
]
}
}
}
}
},
{$unwind : '$contents'} // Purely optional stage - add this stage & test output to decide whether to include or not & add `$project` stage after this stage
])
Тест: игровая площадка