title: Elasticsearch NEST: partial/full-text search without wildcard
body: <p>I want to have a search engine for my users. Let's say user class is:</p>
  
  <pre><code>public class User
  {
      public string Code { get; set; }
      public string Name { get; set; }
  }
  </code></pre>
  
  <p>I have such users in my db:</p>
  
  <pre><code>(1) new User { Code = "XW1234", Name = "John Doe" }, 
  (2) new User { Code = "AD4567", Name = "Jane Doe" }
  </code></pre>
  
  <p>So:
  When my query is: "doe" (mind the lowercase) I want to see (1) and (2)
  When my query is: "4" I want to see (1) and (2)
  When my query is: "x" I want to see (1)
  When my query is: "ja" I want to see (2)
  I want to work similarly as <code>like %doe%</code> in SQL. Please don't mind queries length - I will use 3 letters minimum. This is just an example.</p>
  
  <p>I have a solution with wildcards - works but performance is poor.</p>
  
  <p>I was trying to configure index to use ngram tokenizer but no success - I was receiving an empty collection. </p>
  
  <p>I also checked this ("starts with" approach): 
  <a href="https://www.elastic.co/guide/en/elasticsearch/guide/current/_index_time_search_as_you_type.html" rel="nofollow">https://www.elastic.co/guide/en/elasticsearch/guide/current/_index_time_search_as_you_type.html</a>
  No success.</p>
  
  <p>Please provide the C# code. I don't know if I'm translating the Elastic search jsons correctly.</p>
  
  <p><strong>EDIT</strong> 
  According to the first comment I tried this:</p>
  
  <pre><code>private const string DefaultIndexName = "test";
  private const string ElasticSearchServerUri = @"http://192.168.99.100:32769";
  
  private static readonly IndexName UsersIndexName = "users";
  
  public IElasticClient CreateElasticClient()
  {
      var settings = CreateConnectionSettings();
  
      var client = new ElasticClient(settings);
  
      var studentsIndexDescriptor = new CreateIndexDescriptor(UsersIndexName)
          .Mappings(ms =&gt; ms
              .Map&lt;User&gt;(m =&gt; m
                  .Properties(ps =&gt; ps
                      .String(s =&gt; s
                          .Name(n =&gt; n.Code)
                          .Analyzer("substring_analyzer")))));
      client.CreateIndex(UsersIndexName, descriptor =&gt; studentsIndexDescriptor
          .Settings(s =&gt; s
              .Analysis(a =&gt; a
                  .Analyzers(analyzer =&gt; analyzer
                      .Custom("substring_analyzer", analyzerDescriptor =&gt; analyzerDescriptor.Tokenizer("standard").Filters("lowercase", "substring")))
                  .TokenFilters(tf =&gt; tf
                      .NGram("substring", filterDescriptor =&gt; filterDescriptor.MinGram(2).MaxGram(15))))));
  
      return client;
  }
  
  private static ConnectionSettings CreateConnectionSettings()
  {
      var uri = new Uri(ElasticSearchServerUri);
      var settings = new ConnectionSettings(uri);
      settings
          .DefaultIndex(DefaultIndexName);
  
      return settings;
  }
  </code></pre>
  
  <p>And I used this query:</p>
  
  <pre><code>public IEnumerable&lt;User&gt; Search(string query)
  {
      var result = elasticClient.Search&lt;User&gt;(descriptor =&gt; descriptor
          .Query(q =&gt; q
              .QueryString(queryDescriptor =&gt; queryDescriptor.Query(query).Fields(fs =&gt; fs.Fields(f1 =&gt; f1.Code)))));
      return result.Documents;
  }
  </code></pre>
  
  <p>Didn't work.</p>
  
  <p>I tried Codes: "1234" and "5678". I tried to query with "23", "5" - no results.
  When I search for "1234" - it returns the correct user.</p>