Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ElasticSearch 5.x Context Suggester NEST .Net

I'm trying to create an Index with a context suggester with Nest 5.0 on ElasticSearch 5.1.2.

Currently, I can create the mapping:

elasticClient.MapAsync<EO_CategoryAutocomplete>(m => m
                .Properties(p => p
                    .Completion(c => c
                        .Contexts(ctx => ctx
                            .Category(csug => csug
                                .Name("lang")
                                .Path("l")
                            )
                            .Category(csug => csug
                                .Name("type")
                                .Path("t")
                            )
                            .Category(csug => csug
                                .Name("home")
                                .Path("h")
                            )
                        )
                        .Name(n => n.Suggest)
                    )
                )
            );

But in the POCO class i dont know what object type must be Suggest Property marked with ?????:

public class EO_CategoryAutocomplete
{
    public string Id { get; set; }
    public ????? Suggest { get; set; }
}

public class EO_CategoryAC
{
    public int Id { get; set; }
    public string Name { get; set; }
}

In NEST 5.0 CompletionField Property has been removed (That was the method to do context suggester on elasticsearch 2.X)

Please, can anyone provide an example about how to do it?

The documentation is all about querying. Suggester NEST

Thanks.

like image 663
Oscar André Avatar asked Nov 26 '25 14:11

Oscar André


1 Answers

The Completion and Context Suggester are able to return the _source in the response in 5.x+, so no longer require a payload. Because of this, the type in NEST 5.x is now CompletionField, as opposed to CompletionField<TPayload> in NEST 2.x, where TPayload is the payload type.

Here's an example with NEST 5.x to get you up and running

public class EO_CategoryAutocomplete
{
    public string Id { get; set; }
    public IEnumerable<string> L { get; set; }
    public CompletionField Suggest { get; set; }
}

void Main()
{
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var connectionSettings = new ConnectionSettings(pool)
            .DefaultIndex("autocomplete");

    var client = new ElasticClient(connectionSettings);

    if (client.IndexExists("autocomplete").Exists)
        client.DeleteIndex("autocomplete");

    client.CreateIndex("autocomplete", ci => ci
        .Mappings(m => m
            .Map<EO_CategoryAutocomplete>(mm => mm
                .AutoMap()
                .Properties(p => p
                    .Completion(c => c
                        .Contexts(ctx => ctx
                            .Category(csug => csug
                                .Name("lang")
                                .Path("l")
                            )
                            .Category(csug => csug
                                .Name("type")
                                .Path("t")
                            )
                            .Category(csug => csug
                                .Name("home")
                                .Path("h")
                            )
                        )
                        .Name(n => n.Suggest)
                    )
                )
            )
        )
    );

    client.IndexMany(new[] {
        new EO_CategoryAutocomplete 
        {
            Id = "1",
            Suggest = new CompletionField
            {
                Input = new [] { "async", "await" },
                // explicitly pass a context for lang
                Contexts = new Dictionary<string, IEnumerable<string>>
                {
                    { "lang", new [] { "c#" } }
                }
            }
        },
        new EO_CategoryAutocomplete
        {
            Id = "2",
            Suggest = new CompletionField
            {
                Input = new [] { "async", "await" },
                // explicitly pass a context for lang
                Contexts = new Dictionary<string, IEnumerable<string>>
                {
                    { "lang", new [] { "javascript" } }
                }
            }
        },
        new EO_CategoryAutocomplete
        {
            Id = "3",
            // let completion field mapping extract lang from the path l
            L = new [] { "typescript" },
            Suggest = new CompletionField
            {
                Input = new [] { "async", "await" },
            }
        }
    }, "autocomplete");

    client.Refresh("autocomplete");

    var searchResponse = client.Search<EO_CategoryAutocomplete>(s => s
        .Suggest(su => su
            .Completion("categories", cs => cs
                .Field(f => f.Suggest)
                .Prefix("as")
                .Contexts(co => co
                    .Context("lang", 
                        cd => cd.Context("c#"), 
                        cd => cd.Context("typescript"))
                )
            )
        )
    );

    // do something with suggestions
    var categorySuggestions = searchResponse.Suggest["categories"];
}

The searchResponse returns

{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "suggest" : {
    "categories" : [
      {
        "text" : "as",
        "offset" : 0,
        "length" : 2,
        "options" : [
          {
            "text" : "async",
            "_index" : "autocomplete",
            "_type" : "eo_categoryautocomplete",
            "_id" : "3",
            "_score" : 1.0,
            "_source" : {
              "id" : "3",
              "l" : [
                "typescript"
              ],
              "suggest" : {
                "input" : [
                  "async",
                  "await"
                ]
              }
            },
            "contexts" : {
              "lang" : [
                "typescript"
              ]
            }
          },
          {
            "text" : "async",
            "_index" : "autocomplete",
            "_type" : "eo_categoryautocomplete",
            "_id" : "1",
            "_score" : 1.0,
            "_source" : {
              "id" : "1",
              "suggest" : {
                "input" : [
                  "async",
                  "await"
                ],
                "contexts" : {
                  "lang" : [
                    "c#"
                  ]
                }
              }
            },
            "contexts" : {
              "lang" : [
                "c#"
              ]
            }
          }
        ]
      }
    ]
  }
}

suggesting documents with ids "1" and "3". You can also use Source Filtering to only return the fields that you are interested in from _source.

like image 162
Russ Cam Avatar answered Nov 28 '25 02:11

Russ Cam



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!