Nest(elasticsearch) creating autocomplete

So I have a service that indexes files. any document is like this:

  [ElasticType(IdProperty = "r_object_id", Name = "dm_document")]
  public class dm_document {
    public string r_object_id { get; set; }
    public string i_chronicle_id { get; set; }
    public string object_name { get; set; } // title
    public string title { get; set; } // also a title (don't ask :p )
    public string text { get; set; } // contents of the document
    public string Docbase { get; set; }
  }

So I was wondering on how to optimal index those documents.

So when setting up my analyzers / search queryies i had the following in mind to happen:

  • The search should search on the object_name, title and text.
  • The auto complete should only suggests full words from the tile and
    object_name

I had the following index, but I’m not very experienced with elastic search, so this is probably not good:

client.CreateIndex("testindex", index => index
      .Analysis(analysis => analysis
          .Analyzers(a => a
              .Add(
                  "autocomplete",
                  new Nest.CustomAnalyzer() {
                    Tokenizer = "edgeNGram",
                    Filter = new string[] { "lowercase" }
                  }
              )
          )
          .Tokenizers(t => t
              .Add(
                  "edgeNGram",
                  new Nest.EdgeNGramTokenizer() {
                    MinGram = 1,
                    MaxGram = 20
                  }
              )
          )
      )
      .AddMapping<dm_document>(tmd => tmd
          .Properties(props => props
              .MultiField(p => p
                  .Name(t => t.object_name)
                  .Fields(tf => tf
                      .String(s => s
                          .Name(t => t.object_name)
                          .Index(Nest.FieldIndexOption.NotAnalyzed)
                      )
                      .String(s => s
                          .Name(t => t.object_name.Suffix("autocomplete"))
                          .Index(Nest.FieldIndexOption.Analyzed)
                          .IndexAnalyzer("autocomplete")
                      )
                      .String(s => s
                          .Name(t => t.title)
                          .Index(Nest.FieldIndexOption.NotAnalyzed)
                      )
                      .String(s => s
                          .Name(t => t.title.Suffix("autocomplete"))
                          .Index(Nest.FieldIndexOption.Analyzed)
                          .IndexAnalyzer("autocomplete")
                      )
                      .String(s => s
                          .Name(t => t.text)
                          .Index(Nest.FieldIndexOption.Analyzed)
                          .IndexAnalyzer("snowball")
                      )
                  )
              )
          )
      )
  );

and I used the following API functions:

// GET api/autocomplete
public IEnumerable<object> Get(string search = "", int from = 0, int size = 50) {
  var c = new ElasticClient();
  var results = c.Search<dm_document>(s => s
      .From(from)
      .Size(size)
      .Query(q => q.Term(d => d.object_name.Suffix("autocomplete"), search))
  );

  return results.Documents.Select(d => new { d.title, d.r_object_id }).ToList();
}

and

// GET api/search
public List<dm_document> Get(string search = "", int from = 0, int size = 50) {
  var indexservice = new IndexService();

  var c = new ElasticClient();
  var result = c.Search<dm_document>(s => s
      .From(from)
      .Size(size)
      .Query(q => q.Term(d => d.text, search))
  );
  return result.Documents.ToList();
}

also for some reason the title is empty in when indexed (could be my mistake on setting the dm_document)


Source: .net

Leave a Reply