1
votes

This is probably just me completely overseeing the obvious "missing link". Here goes anyway: I have an elasticsearch end-point http://distribution.virk.dk/cvr-permanent/virksomhed/_search, and I would like to query on this end-point. Fairly simple.

As I understand, NEST gives you the ability to strongly type the interaction with the elasticsearch index, in much the same way as Visual Studio will create types for a asmx/svc when you add a reference to the respective service.

So my question is: how on earth do I get from knowing the end-point for an elasticsearch index to having types matching the index and making queries on the index? I pressume the answer is: "Use NEST!", but all tutorials I've been able to find assume you have a local index that you generate from a c#-type, which will then give you a type to use in your queries. But what to do, when it's a "remote" index that you have to build your types from?

Thanks in advance for any answer pointing in the right direction!

UPDATE:

I have retrieved the mappings in the index, which I have reduced to only the field "cvrNummer" in the following:

{
"cvr-permanent-prod-20170205" : {
"mappings" : {
  "virksomhed" : {
    "_size" : {
      "enabled" : true
    },
    "properties" : {
      "Vrvirksomhed" : {
        "properties" : {

            "type" : "long"
          },
          "cvrNummer" : {
            "type" : "string"
          },             

          }
        }
      },          
    }
  }
  }
 }
 }

I have then made the following class:

[ElasticsearchType(Name = "virksomhed")]
public class Company
{
    [Text(Name = "cvrNummer")]
    public string cvrNumber { get; set; }
}

Now, all that I want to do (to begin with) is to search for documents having cvrNummer with a certain value, f. ex. "12883404". I have the following code in a simple console application:

var node = new Uri("http://distribution.virk.dk/cvr-
permanent/virksomhed/_search");

        var settings = new ConnectionSettings(node).DefaultIndex("defaultindex");

        settings.BasicAuthentication("username", "password");            

        var client = new ElasticClient(settings);

I then try the following very simple request:

var searchResponse = client.Search<Company>(s => s
.Type<Company>()
.Query(q => q
     .Match(m => m
        .Field(f => f.cvrNumber)
        .Query("12883404")

And I get "400 bad request". What on earth am I doing wrong?

1

1 Answers

0
votes

Basically you create a C# class with the properties you need by hand, then tell nest to map the results to this class.

using Nest;
using System;

[ElasticsearchType(Name = "Name_Of_The_Mapping_In_Index_Mappings")]
public class MySearchType {

        [Text(Name = "_id")]
        public string Id { get; set; }

        [Date(Name = "@timestamp")]
        public DateTime Timestamp { get; set; }

        [Number(NumberType.Long, Name = "some_numeric_property_in_the_mapping")] 
        public long SomeNumericProperty { get; set; }
}

Then you can type your results to the search type you just defined:

Task<ISearchResponse<MySearchType>> response = await _elasticClient.SearchAsync<MySearchType>(s => s
    .Index("Name_Of_The_Index")
    .Type<MySearchType>()
    .Query(q => 
        q.Bool(bo => 
             bo.Filter( 
                 f => f.Terms(t => 
                     t.Field(searchtype => searchtype.SomeNumericProperty).Terms(request.NumericInput)),
                 /* ... */
             )
         )
     )
);

IReadOnylCollection<MySearchType> result = response.Documents;

This explains how you can retrieve the names needed to create the binding: Get all index and types' names from cluster in ElasticSearch.