Watch keynotes and sessions from MongoDB.live, our virtual developer conference.

Return only array items that matches $text

Hello, i use mongoose with node.js

This is an example of my User document:

user: {
 _id: "xxx",
 name: "Lucas",
 items: [
  { name: "shoes", description: "nice shoes" },
  { name: "pants", description: "old pants" },
 ],
 places: [
  {name: "my house", loc: { type: "Point", coordinates: [-27, -43] }}
 ]
}

I need to perform a text-search ($text) that returns only the items. For example:

await User.find({ $text: { $search: "shoes" } });

This works! But it also returns pants, since it returns the user and not only the array item. And that is the problem, i need to paginate over the items in my database. So I need to return only the array items that matches the $text search. I know that if items was a collection itself it would work, but in my case I need those inside the user because I combine $text for items and $geoWithin for places.

So, how do I return the User keeping only his items that matched my $text search?

I think you are looking to return something like this: { name: "shoes", description: "nice shoes" }.

You use a projection to limit the fields to be in the result document. But, when you have to project only a filtered set of array elements, the find method has a limited use. Using $elemMatch projection operator you can project only the first matching element.

To project all the matching items use the aggregate method on the collection. Aggregation has $project and this can be used with the $filter array operator to get all the matching array elements. Another way is, to use a combination of $unwind, $match and $project stages.

[ EDIT ADD ]

Here is the link to a post with an example aggregate query about using the $filter on an array: Java driver - $filter aggregation operator