How to create Search Index for text field inside nested array of objects

Hello:

I have a nested array of objects in my document as follows:

{
_id: “xyz”,
deos: [
{_id: “123”,
text: “guitar”
},
{_id:“124”,
text:“mango”
]
}

Now I am able to use the Atlas Text Search. Lets say I search for “guitar” it returns the entire collection. However I only want it to return those nested objects that contain the keyword guitar. How do I accomplish this?

I am not seeing a straightforward solution to this simple use case and would request someone from Mongodb to please look into it. In a nosql database creating embedded documents in the the way to structure relationships in many cases. So I have a nested array of objects. I do a $Search full text search on a nested object in a nested array and I get the parent collection back. The actual search results are in an object inside a nested array. So how then do I get a reference to the objects that the full text search found? I don’t need the entire document I need to be able to filter only those objects in the embedded/nested array that the $search found a match for. How do I do this?

Dear @Arjun_kochhar_leodeo ,

Welcome to The MongoDB Community forums! :wave:

To get a better understanding of your use-case, could you please confirm below?

After you perform this search, do you mean you get back the whole collection (with all documents, even when they don’t contain the “guitar” term you’re looking for), or documents in which guitar is present (e.g. not the whole collection), but not in the format that you wanted?

For example, do you only want the nested object, something like below after your search?

{_id:“124”,
text:“mango”}

Also, could you please share the below details:

  • What is your Atlas cluster (M0/M2…etc)?
  • The queries you have tried
  • The output you’re expecting

Regards,
Tarun

Hello @Tarun_Gaur,

Thanks for your response. My question was about search a “nested” array specifically. If a word is found in a nested array of a document, it returns the entire document. My issue was then it also returns all the other items in the nested array where the search term does not match.

For me the solution seems to be to use $project as follows:

const agg = [
  {
    '$search': {
      'text': {
        'query': 'electric',
        'path': 'deos.text'
      },
      'highlight': {
        'path': 'deos.text'
      }
    }
  }, {
    '$limit': 10
  }, {
    '$project': {
      '_id': 1,
      'given_name': 1,
      'highlights': {
        '$meta': 'searchHighlights'
      },
      'score': {
        '$meta': 'searchScore'
      }
    }
  }
];

For those who follow I will clarify. Deos is a nested array in the collection that I am doing the $search on. I want to to search for the word “electric” in this nested array. If I don’t use the $meta operator in the $project, I get the whole collection back if there is ANY match in the deos. text nested array for the word electric. This is useless, because what is the point of the search if I get the whole collection back because there is a match.

The solution for me seems to be the “highlights” in the $project. This object contains the precise places in deos.text where there is a match. I can take this and process it further in Javascript.

This is the solution for me.

1 Like

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.