Search stage filter for empty array

Hey,
I’ve got a case where I need to use the filter operator in $search stage combined with should clause
My goal is to match field that is empty array, but I don’t see how I can do that with those operators
autocomplete, compound, embeddedDocument, equals, exists, geoShape, geoWithin, in, knnBeta, moreLikeThis, near, phrase, queryString, range, regex, search, span, term, text, wildcard

it should be something like this

      equals: {
        path: 'geo_locations',
        value: [],
      }

But as we know equals doesn’t work with empty array so I’m looking for an alternative

Hey @Ivan_Kraev,

If I understand correctly, your ‘geo_location’ field contains Geo coordinates represented numerically within an array, and you’re looking to filter out the empty arrays – Currently, Atlas Search does not have an operator that checks for empty arrays.

One possible workaround I can think of is to convert these numeric values to strings. You can consider creating a materialized view that stores the numeric values as strings. For more details, please refer to the How to Run Atlas Search String Queries Against Date and Numeric Fields documentation.

In the scenario you provided, your geo_location field in the Materialized view appears as follows:

[
  { geo_location: [] },
  { geo_location: [ '-69.3547792', '8.547792'] },
  { geo_location: [ '-79.9081268', '9.3547792' ] },
  { geo_location: [] },
  { geo_location: [ '-73.7465439', '18.1898632' ] },
  { geo_location: '' },
  { geo_location: [ '-72.7045822', '19.4582243' ] }
]

Now, you can form a query that can return the resultant documents as per your conditions. Here is the example query for your reference:

db.getCollection('test').aggregate(
  [
    {
      $search: {
        index: 'geo_index',
        compound: {
          must: {
            exists: { path: 'geo_location' }
          },
          mustNot: {
            wildcard: {
              path: 'geo_location',
              query: '*',
              allowAnalyzedField: true
            }
          }
        }
      }
    }
  ],
);

It will return the following output result: (If you have a document with an empty string, this will also be returned).

[
  { _id: ObjectId('65797b99ec0e32327fc5bd7c'), geo_location: [] },
  { _id: ObjectId('65797b99ec0e32327fc5bd7f'), geo_location: [] },
  { _id: ObjectId('657a6cd7a71ee0047e1c23e8'), geo_location: '' }
]

Note: Please thoroughly test and verify to make sure it suits your use case/requirements.

Additionally, I would encourage you to provide some feedback about your use case here so that others can also vote for it, which will help us drive it forward!

Hope it helps!

Best regards,
Kushagra

1 Like