How to use the Serialize method from the ElasticCl

2019-09-14 00:17发布

问题:

I've created a successful connection to ES, and then written my json query. Now, I would like to send that query via the Serialize method. The Serialize method requires two parameters:

1. object and 2. Stream writableStream

My question is, with the second one. When I create a stream with the following code line:

Stream wstream;

And use it to initialize my json2 variable with the following code:

var json2 = highLevelclient.Serializer.Serialize(query, wstream).Utf8String();

I get the following error on the wstream variable:

Use of unassigned local variable 'wstream'.

Am I missing something? Is it the way I create the wstream variable that is wrong? thank you.


/* \\\ edit: ///// */ There is another issue now, I use Searchblox to index and search my files, which itself calls ES 2.x to do the job. Searchblox uses a "mapping.json" file to initialize a mapping upon the creation of an index. Here's the link to that file. As "@Russ Cam" suggested, I created my own class content with the following code (just like he did with the "questions" index and "Question" class):

 public class Content
    {
        public string type { get; set; }
        public Fields fields { get; set; }
    }

    public class Fields
    {
        public Content1 content { get; set; }
        public Autocomplete autocomplete { get; set; }
    }

    public class Content1
    {
        public string type { get; set; }
        public string store { get; set; }
        public string index { get; set; }
        public string analyzer { get; set; }
        public string include_in_all { get; set; }
        public string boost { get; set; }
    } //got this with paste special->json class

These fields from the content class (type,store etc.) come from the mapping.json file attached above. Now, when I (just like you showed me) execute the following code:

var searchResponse = highLevelclient.Search<Content>(s => s.Query(q => q
         .Match(m => m.Field(f => f.fields.content)
        .Query("service")

All I get as a response on the searchResponse variable is:

Valid NEST response built from a successful low level call on POST: /idx014/content/_search
Audit trail of this API call:
 -HealthyResponse: Node: http://localhost:9200/ Took: 00:00:00.7180404
Request:
{"query":{"match":{"fields.content":{"query":"service"}}}}
Response:
{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

And no documents in searchResponse.Documents. Contradictorily, when I search for the "service" query on Searchblox or make an API call to localhost:9200 with the Sense extension of Google Chrome, I get 2 documents. (the documents that I was looking for)

In brief, all I want is to be able to :

  1. get all the documents (no criteria)
  2. get all the documents within a time range and based upon keywords.. such as "service"

What am I doing wrong? I can provide with more information if needed.. Thank you all for your detailed answers.

回答1:

It's actually much simpler than this with NEST :) The client will serialize your requests for you and send them to Elasticsearch, you don't need to take the step to serialize them yourself and then pass them to the client to send to Elasticsearch.

Take a search request for example. Given the following POCO

public class Question
{
    public string Body { get; set; }
}

We can search for questions that contain the phrase "this should never happen" in the body with

var settings = new ConnectionSettings(new Uri("http://localhost:9200"))
    .InferMappingFor<Question>(m => m
        .IndexName("questions")
    );


var client = new ElasticClient(settings);

var searchResponse = client.Search<Question>(s => s
    .Query(q => q
        .MatchPhrase(m => m
            .Field(f => f.Body)
            .Query("this should never happen")
        )
    )
);

// do something with the response
foreach (var question in searchResponse.Documents)
{
    Console.WriteLine(question.Body);
}


回答2:

this line

My question is, with the second one. When I create a stream with the following code line:

Stream wstream;

does not create na object. It nearly declares it. You need to new-ed it.

Stream wstream = new MemoryStream(); //doesn't have to be MemoryStream here - check what does Serialize expects

Just remember to close it later or use using statement.

using(Stream stream = new MemoryStream())
{

   //do operations on wstream

} //closes automatically here


回答3:

You just declared wstream but never assigned an actual stream to it. Depending on how Serialize method works it could be:

  • you need to create a stream and pass it to the Serialize method
  • or you need to pass stream parameter with out prefix