Serialising an object to JSON, and then using that

2019-01-29 05:00发布

I get a bit confused and frustrated when it comes to using NEST to querying, as it seems very hit and miss. I have no trouble querying when using standard JSON, so I was wondering if there was some way to query using a JSON object, I have code below

var query = "bkala";

var q = new
{
    query = new
    {
        text = new
        {
            _all = "jane"
        }
    }
};

var qJson = JsonConvert.SerializeObject(q);
var hits = client.Search<Users>(qJson);

However, I get the error "Cannot convert from type string to System.Func, Nest.ISearchRequest"

If anyone knows how I can simply query using a JSON object, that would be fantastic, cheers in advance.

1条回答
手持菜刀,她持情操
2楼-- · 2019-01-29 05:31

NEST and Elasticsearch.Net, the low level client that NEST uses under the covers, are flexible in how you wish to query. With NEST you have a couple of different ways:

NEST - High level client

1.Fluent API

var query = "bkala";

var searchResult = client.Search<MyDocument>(s => s
    .Query(q => q
        .Match(m => m
            .Field("_all")
            .Query(query)
        )
    )
);

Laid out as above, this API uses lambda expressions to define a fluent interface that mimics the structure of the Elasticsearch json API and query DSL.

2.Object Initializer Syntax

var query = "bkala";

var request = new SearchRequest<MyDocument>
{
    Query = new MatchQuery
    {   
        Field = "_all",
        Query = query
    }
};

var searchResult = client.Search<MyDocument>(request);

If lambda expressions are not your thing, then you can always define your searches using specific search types.

Elasticsearch.Net - Low level client

In cases where you would like to query with anonymous types (as per your question), json strings or a byte representation of a query, then you can use the low level client, Elasticsearch.Net, to achieve this. The low level client is exposed on the high level client through the .LowLevel property

1.Anonymous types

var query = new
{
    query = new
    {
        match = new
        {
            _all = new
            {
                query = "bkala"
            }
        }
    }
};

var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(query);

Using the low level client on the high level client means that you can still take advantage of using Json.NET to deserialize search results; in this example, the search response can be accessed through searchResult.Body

2.Json string

var query = @"
{
  ""query"": {
    ""match"": {
      ""_all"": {
        ""query"": ""bkala""
      }
    }
  }
}";

var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(query);

3.Byte array

var bytes = new byte[] { 123, 13, 10, 32, 32, 34, 113, 117, 101, 114, 121, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 34, 109, 97, 116, 99, 104, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 34, 95, 97, 108, 108, 34, 58, 32, 123, 13, 10, 32, 32, 32, 32, 32, 32, 32, 32, 34, 113, 117, 101, 114, 121, 34, 58, 32, 34, 98, 107, 97, 108, 97, 34, 13, 10, 32, 32, 32, 32, 32, 32, 125, 13, 10, 32, 32, 32, 32, 125, 13, 10, 32, 32, 125, 13, 10, 125 };

var searchResult = client.LowLevel.Search<SearchResponse<MyDocument>>(bytes);

All of the above methods produce the following query

{
  "query": {
    "match": {
      "_all": {
        "query": "bkala"
      }
    }
  }
}

Check out the Getting started guide on the github repo as well as the documentation on the Elastic website. We are continually working to improve documentation and PRs are more than welcome for areas where you feel we are lacking :)

查看更多
登录 后发表回答