[atlas search] how to exact array match?

I want to get the exact match value of a specific array.
input: { “filter.schedule” : [“sat”, “sun”]}

example data :

{
 scheduleDays: ['sat', 'sun']
},
{
 scheduleDays: ['sun']
},
{
 scheduleDays: ['sat']
},
{
 scheduleDays: ['mon', 'sun']
} ...

i hope trying to

[
  {
    $match: {
      $or: [
        {
          "scheduleDays": {
            $eq: ["sat", "sun"],
          },
        },
        {
          "scheduleDays": {
            $eq: ["sat"],
          },
        },
        {
          "scheduleDays": {
            $eq: ["sun"],
          },
        },
      ],
    },
  },
]

so, i tried convert atlas search compound query.

[
  {
    $search: {
      // index: "",
      compound: {
        filter: [
          {
            equals: {
              path: "isActive",
              value: true,
            },
          },
          {
            geoWithin: {
              path: "location",
              circle: {
                center: {
                  type: "Point",
                  coordinates: [
                    // 0,
                    // 0
                  ],
                },
                radius: 50000,
              },
            },
          },
          {
            compound: {
              should: [
                {
                  text: {
                    path: "scheduleDays",
                    query: ["sat", "sun"],
                  },
                },
                {
                  text: {
                    path: "scheduleDays",
                    query: ["sat"],
                  },
                },
                {
                  text: {
                    path: "scheduleDays",
                    query: ["sun"],
                  },
                },
              ],
            },
          },
        ],
        must: [
          {
            near: {
              origin: {
                type: "Point",
                coordinates: [
                 // 0,
                  // 0
                ],
              },
              pivot: 5000,
              path: "location",
              score: {
                boost: {
                  value: 3,
                },
              },
            },
          },
        ],
        should: [],
      },
      count: {
        type: "total",
      },
      scoreDetails: true,
      highlight: {
        path: [
          // ""
        ],
      },
    },
  },
  {
    $limit: 20,
  },
  {
    $skip: 0,
  },
  {
    $addFields: {
      scoreDetails: {
        $meta: "searchScoreDetails",
      },
      score: {
        $meta: "searchScore",
      },
      highlights: {
        $meta: "searchHighlights",
      },
      total: "$$SEARCH_META.count.total",
    },
  },
]

Is it possible to change compound.filter to $eq syntax, not $in?

thx.

Hi @wrb and welcome to MongoDB community forums!!

I see that response to your question has been pending for a while now. While I hope that the issue must have been resolved, this is how I would like to resolve the query.

Currently, Atlas search indexes array elements as described in How Does Atlas Search Index Array Elements? documentation.

While I would love to take this internally to the relevant team, I would like to know your specific use case (including if positioning matters) and the condition that could not be satisfied using the currently present operators .

As mentioned the official MongoDB documentations for $equals, it could be used only to ObjectID, boolean, number and dates.

In saying so, I assume since you are after an equivalent to $eq you want position to matter. However, in the case position doesn’t matter and since I note that the scheduleDays contains the days in a week, one workaround would be to use queryString AND and AND NOT boolean operators after deciding the days you are wanting (application side) to return in a format similar to below:

{
$search: {
index: 'default',
queryString: {
defaultPath: 'scheduleDays',
query: '(sun AND sat) AND NOT (mon OR tue OR wed OR thu OR fri)'
}
}
}

The first portion of the query would be days you wish to return and the second portion (after the AND NOT would contain the remaining days) - This could possibly be calculated application side beforehand.Based off your sample documents, the above query would return the first document only.

Please reach out if you have further questions.

Regards
Aasawari

1 Like

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