Since your collection is huge 100m, try indexing the fields, and do $text
search on collection
creating text index
https://docs.mongodb.com/manual/core/index-text/
$text
search
https://docs.mongodb.com/manual/reference/operator/query/text/index.html
> db.books.ensureIndex({"$**" : "text"})
index
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 2,
"note" : "all indexes already exist",
"ok" : 1
}
result
>
> db.books.find({$text : {$search : "ch2"}})
{ "_id" : 2, "chapters" : { "0" : { "title" : "ch4" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch5" } }, "description" : "book two" }
{ "_id" : 1, "chapters" : { "0" : { "title" : "ch1" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch3" } }, "description" : "book one" }
>
This is possible with out text index, by to converting the chapters $objectToArray
for searching and back to $arrayToObject
, but this will do this for 100m documents, not suitable for your case
db.books.aggregate(
[
{$project : { description : 1, arr : {$objectToArray : "$$ROOT.chapters"}}},
{$match : {"arr.v.title" : "ch2"}},
{$project : { description : 1 , chapters : { $arrayToObject : "$$ROOT.arr"}}}
]
).pretty()
result
> db.books.aggregate([{$project : { description : 1, arr : {$objectToArray : "$$ROOT.chapters"}}}, {$match : {"arr.v.title" : "ch2"}}, {$project : { description : 1 , chapters : { $arrayToObject : "$$ROOT.arr"}}}])
{ "_id" : 1, "description" : "book one", "chapters" : { "0" : { "title" : "ch1" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch3" } } }
{ "_id" : 2, "description" : "book two", "chapters" : { "0" : { "title" : "ch4" }, "1" : { "title" : "ch2" }, "2" : { "title" : "ch5" } } }
>