Atlas search not matching results that contain _

Given the following Atlas Search Index and example data…

Atlas Search Index

{
  mappings: {
    dynamic: false,
    fields: {
      title: {
        type: 'string',
        norms: 'omit',
      },
      content: {
        type: 'string',
        norms: 'omit',
      },
    },
  },
  name: 'DocumentSearch',
}

Example Data

[
  { 
    _id: 1, 
    title: 'My first document', 
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  },
  { 
    _id: 2, 
    title: 'My first_document', 
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  },
]

I’m trying to searching for “my document” and I’m expecting to get back both documents but getting back none. Additionally, searching for “my fir” returns no documents and I’d expect it to return both.

Search Query

{
  $search: {
    index: 'DocumentSearch',
    compound: {
      minimumShouldMatch: 1,
      should: [
        {
          phrase: {
            path: 'title',
            query,
            slop: 4,
            score: { boost: { value: 3 } },
          },
        },
        {
          phrase: {
            path: 'content',
            query,
            slop: 4,
          },
        },
      ],
    },
    highlight: {
      path: 'content',
    },
  },
}

What changes do I need to make to my query or index to support my desired outcome?

Hi @Brandon,

I understand you have "norms" set to "omit" for your current index but i’m wondering if using autocomplete suits your use case here? Some examples below for the search terms you mentioned above:

Using "my fir" as the search term:

documets> a
{
  '$search': {
    compound: {
      minimumShouldMatch: 1,
      should: [
        { autocomplete: { query: 'my fir', path: 'content' } },
        { autocomplete: { query: 'my fir', path: 'title' } }
      ]
    }
  }
}
documets> db.collection.aggregate(a)
[
  {
    _id: 1,
    title: 'My first document',
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  },
  {
    _id: 2,
    title: 'My first_document',
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  }
]

Using "my document" as the search term:

documets> b
{
  '$search': {
    compound: {
      minimumShouldMatch: 1,
      should: [
        { autocomplete: { query: 'my document', path: 'content' } },
        { autocomplete: { query: 'my document', path: 'title' } }
      ]
    }
  }
}


documets> db.collection.aggregate(b)
[
  {
    _id: 1,
    title: 'My first document',
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  },
  {
    _id: 2,
    title: 'My first_document',
    content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit'
  }
]

This is just a basic example of autocomplete based off the search terms and sample documents provided but you could probably alter it accordingly to fit your use case. More information regarding the autocomplete type and operator linked :slight_smile:

For reference, the index used for the above examples in my test environment:

{
  "mappings": {
    "dynamic": true,
    "fields": {
      "content": {
        "type": "autocomplete"
      },
      "title": {
        "type": "autocomplete"
      }
    }
  }
}

Additionally, the reason why you may not be getting any results returned is due to the phrase opeator. You can see an example of this here as well which describes the behaviour for a single phrase.

Hope this helps.

Regards,
Jason