Not getting any results for a field that requires exact match

I'm building a search feature that allows users to filter by certain field. One of the field is DOI. Filtering by DOI should only return results with exact match.

I'm trying to index the following object:

public class PaperElasticSearchModel
    {
        public string Title { get; set; }
        public string Abstract { get; set; }
        public string Keywords { get; set; }
        public string DOI { get; set; }
        public int Year { get; set; }
        public string[] Author { get; set; }
    }

The field DOI is will have a similar format to this: 10.1523/JNEUROSCI.18-04-01622.1998.

Below is the setting for the index

Client.Indices.Create(index, pub => pub
.Settings(s => s
 .Analysis(descriptor => descriptor
     .Analyzers(analyzer => analyzer
         .Custom("custom_analyzer", ca => ca
             .Filters("lowercase", "stop", "classic", "word_delimiter")
             )
         )
         
    .TokenFilters(bases => bases
         .EdgeNGram("custom_analyzer", td => td
         .MinGram(2)
         .MaxGram(25))
         )
    )
 .Setting(UpdatableIndexSettings.MaxNGramDiff, 23)
 )
.Map<PubScreenSearch>(m => m
 .AutoMap()
 .Properties(p => p
     .Text(t => t
         .Name(f => f.Author)
         .Analyzer("custom_analyzer"))
     .Text(t => t
         .Name(f => f.Keywords)
         .Analyzer("custom_analyzer"))
     .Text(t => t
         .Name(f => f.Title)
         .Analyzer("custom_analyzer"))
     .Keyword(t => t
         .Name(f => f.DOI)
     )
     
 )));

Here is the filter query that is used:

else if (pi.Name == "DOI")
  {
      filterQuery.Add(fq => fq
                  .Term(new Nest.Field(pi.Name.ToLower()), value)
              );
  }

What Analyzer should I use such that if I were to search by DOI it would return for exact match?

Hi @Sujinthan

If the DOI field is a keyword, you are already indexing without applying any analyzer and to search for the exact term, Term Query is recommended.

Hi @RabBit_BR
Unfortunately that did not work. I think there is something wrong with the way I index my object.

Here I'm searching for a document where the title is mouse. I get the following results:

If I search for the DOI (underlined in red) I don't see any results:

POST /pubscreen/_search
  {
    "query": {

                "term": {
                    "dOI": {
                        "value": "10.1177/0301006615614440"
                    }
                }
    }
  }
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 0,
      "relation": "eq"
    },
    "max_score": null,
    "hits": []
  }
}

provide your mapping/settings:

GET pubscreen

Field "dOI" should be:

 "properties": {
      "dOI": {
        "type": "keyword"
      }
    }

It is not...

"dOI": {
  "type": "text",
  "fields": {
    "keyword": {
      "type": "keyword",
      "ignore_above": 256
    }
  }
},

Here is how I'm creating the Index

 Client.Indices.Create(index, pub => pub
 .Settings(s => s
     .Analysis(descriptor => descriptor
         .Analyzers(analyzer => analyzer
             .Custom("custom_analyzer", ca => ca
                 .Filters("lowercase", "stop", "classic", "word_delimiter")
                 )
             )
        .TokenFilters(bases => bases
             .EdgeNGram("custom_analyzer", td => td
             .MinGram(2)
             .MaxGram(25))
             )
        )
     )
 .Map<PubScreenSearch>(m => m
     .AutoMap()
     .Properties(p => p
         .Text(t => t
             .Name(f => f.Author)
             .Analyzer("custom_analyzer"))
         .Text(t => t
             .Name(f => f.Keywords)
             .Analyzer("custom_analyzer"))
         .Text(t => t
             .Name(f => f.Title)
             .Analyzer("custom_analyzer"))
         .Keyword(t => t
             .Name(f => f.DOI))
         )
     )
 );

I'm following this documentation for Elasticsearch v7.17, however I'm using Elasticsearch v8.12, I don't think this is an issue.

It looks like that field was mapped using dynamic mapping. This means it has a multi field keyword that is mapped as keyword, so use this instead as follows:

Thank you @RabBit_BR and @Christian_Dahlqvist for helping me with this.
After following @Christian_Dahlqvist advice I was able to resolve this issue.

Since this is mapped dynamically, I needed my query to be written as the following:

filterQuery.Add(fq => fq
            .Bool(f => f
                .Must(boolSHould => boolSHould
                    .Term(t => t
                        .Field(feild => feild.DOI.Suffix("keyword"))
                        .Value(value))
                        ))
            
        );
1 Like