Atlas Search - search in array of objects with text operator as AND condition

Hello!

I have the following documents in my MongoDB collection:

[
    { 
        "hotelName": "Hotel ABC",
        "facilities": [
            { "id": "free-wifi", "title": "Free Wi-Fi" },
            { "id": "by-the-beach", "title": "By the beach" },
            { "id": "facilities-for-disabled", "title": "Facilities for disabled" }
        ]
    },
    { 
        "hotelName": "Hotel DEF",
        "facilities": [
            { "id": "for-elders", "title": "For elders" },
            { "id": "by-the-beach", "title": "By the beach" },
            { "id": "facilities-for-disabled", "title": "Facilities for disabled" }
        ]
    },
    { 
        "hotelName": "Hotel GHI",
        "facilities": [
            { "id": "free-wifi", "title": "Free Wi-Fi" },
            { "id": "spa-zone", "title": "SPA Zone" },
            { "id": "facilities-for-disabled", "title": "Facilities for disabled" }
        ]
    }
]

Now I want to search hotels with both “Free Wi-Fi” and “By the beach” facilities included, so I’m doing the following query:

[
    {
      $search: {
        index: "hotels_content",
        embeddedDocument: {
          path: "facilities",
          operator: {
            compound: {
              must: [
                {
                  text: {
                    path: "facilities.id",
                    query: [
                      "free-wifi",
                      "by-the-beach",
                    ],
                  },
                },
              ],
            },
          },
        },
      },
    },
  ]

But this query is not working as I expected, looks like it’s using OR expression in text operator, so all 3 documents are returned. How can I change this query to use AND expression in the text filter so only the first document will be returned?

1 Like

Since a query array performs an OR search you need to add multiple embeddedDocument operators to the compound must array.

[
	{
		$search: {
			index: "hotels_content",
			compound: {
				must: [
					{
						embeddedDocument: {
							path: "facilities",
							operator: {
								text: {
									path: "facilities.id",
									query: "free-wifi"
								}
							}
						}
					},
					{
						embeddedDocument: {
							path: "facilities",
							operator: {
								text: {
									path: "facilities.id",
									query: "by-the-beach"
								}
							}
						}
					}
				]
			}
		}
	}
]

I’m looking for the same solution and this was the best I could come up with. If anyone has a better idea please comment!

3 Likes

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