问题
I'm using NEST for ES in .net
This is how im indexing a doc. (Wrote all the elastic client connections in a different class called Settings)
so on a button click
client = Settings.connection();
var res1 = new Class1
{
Id = 1,
Ans = "The quick brown fox jumps over the lazy dog"
};
if (client.IndexExists("zzz").Exists == true)
{
client.Index(res1);
}
string ans = getInfo();
process(ans);
public string getInfo(){
string wordInfoQuery = @"{
""query"": {
""match_phrase"":{
""Answer"":{
""query"": ""brown dog"",
""slop"": "3"
}
}
}
}";
try
{
if (client != null)
{
var callResult = client.LowLevel.Search<string>(wordInfoQuery);
reply = callResult.Body.ToString();
e.Write(callResult.Body);
}
}
return reply;
}
public void process(string answer)
{
if (!string.IsNullOrEmpty(answer))
{
byte[] byteArray = Encoding.UTF8.GetBytes(answer);
MemoryStream m = new MemoryStream(byteArray);
float score;
using (StreamReader r = new StreamReader(m))
{
string json1 = r.ReadToEnd();
JObject jobj1 = JObject.Parse(json1);
JToken agg1 = jobj1.GetValue("hits")["max_score"];
if (agg1!=null) //getting an error here most of the times. if the max_score field is null (for eg: instead of brown dog if i send "tax" as a query term)
{
score = agg1.ToObject<float>();
}
else
{
score = 0;
}
}
}
}
class Settings{
public static ElasticClient connection()
{
configvalue1 = ConfigurationManager.AppSettings["url"];//stored the url in web.config (http://localhost:9200)
node = new Uri(configvalue1);
settings = new ConnectionSettings(node)
.DefaultIndex("zzz")
.MapDefaultTypeNames(m => m.Add(typeof(Class1), "omg"));
client = new ElasticClient(settings);
if (client.IndexExists("zzz").Exists)
{
client.DeleteIndex("zzz"); //i want to index only one doc at a time. so deleting and creating everytime i click on the button
client.CreateIndex("zzz");
}
return client;
}
}
In the above code, when i run the code in debug mode, I'm getting a successful post message with query result(for eg. max_Score = 0.28) where as if i run the code in browser mode, it is still making a call to ES , but the result is empty(max_score =""). I dont know why is this happening. someone please help in solving this.
thanks in advance
回答1:
A few observations:
- You use
"Answer"as the field name for thematch_phrasequery in your json but NEST by default will camel case all CLR property names when mapping, indexing, searching, etc. This should be"answer"or change the default field name inference on Connection Settings - When there are no results for a
match_phrasequery,max_scorewill benullso you will need to handle this case. In your example, aslopof 3 produces no hits for the query somax_scoreisnull. If you changeslopto 5, you get the document back and a value formax_score. - I'd recommend using the Fluent API or the Object Initializer Syntax in NEST unless you have good reason not to (and if you do have a reason, we'd love to know!). There are usage examples of all of the Query DSL for NEST 2.x that should hopefully help :)
An example
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "zzz";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex)
.MapDefaultTypeNames(m => m.Add(typeof(Class1), "omg"))
.PrettyJson()
.DisableDirectStreaming()
.OnRequestCompleted(response =>
{
// log out the request
if (response.RequestBodyInBytes != null)
{
Console.WriteLine(
$"{response.HttpMethod} {response.Uri} \n" +
$"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
}
else
{
Console.WriteLine($"{response.HttpMethod} {response.Uri}");
}
// log out the response
if (response.ResponseBodyInBytes != null)
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
$"{new string('-', 30)}\n");
}
else
{
Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
$"{new string('-', 30)}\n");
}
});
var client = new ElasticClient(connectionSettings);
if (client.IndexExists(defaultIndex).Exists)
{
client.DeleteIndex(defaultIndex);
}
client.CreateIndex(defaultIndex);
client.Index(new Class1
{
Id = 1,
Answer = "The quick brown fox jumps over the lazy dog"
}, i => i.Refresh());
var searchResponse = client.Search<Class1>(s => s
.Query(q => q
.MatchPhrase(mp => mp
.Field(f => f.Answer)
.Query("brown dog")
.Slop(5)
)
)
);
Console.WriteLine(searchResponse.MaxScore);
}
public class Class1
{
public int Id { get; set; }
public string Answer { get; set;}
}
Writes out the following to the console
HEAD http://localhost:9200/zzz?pretty=true
Status: 200
------------------------------
DELETE http://localhost:9200/zzz?pretty=true
Status: 200
{
"acknowledged" : true
}
------------------------------
PUT http://localhost:9200/zzz?pretty=true
{}
Status: 200
{
"acknowledged" : true
}
------------------------------
PUT http://localhost:9200/zzz/omg/1?pretty=true&refresh=true
{
"id": 1,
"answer": "The quick brown fox jumps over the lazy dog"
}
Status: 201
{
"_index" : "zzz",
"_type" : "omg",
"_id" : "1",
"_version" : 1,
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"created" : true
}
------------------------------
POST http://localhost:9200/zzz/omg/_search?pretty=true
{
"query": {
"match": {
"answer": {
"type": "phrase",
"query": "brown dog",
"slop": 5
}
}
}
}
Status: 200
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.07829509,
"hits" : [ {
"_index" : "zzz",
"_type" : "omg",
"_id" : "1",
"_score" : 0.07829509,
"_source" : {
"id" : 1,
"answer" : "The quick brown fox jumps over the lazy dog"
}
} ]
}
}
------------------------------
0.07829509
来源:https://stackoverflow.com/questions/36732860/elastic-search-using-nest-results-different-in-debug-and-browser-mode