A few observations
- You use
"Answer"
as the field name for the match_phrase
query 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_phrase
query, max_score
will be null
so you will need to handle this case. In your example, a slop
of 3 produces no hits for the query so max_score
is null
. If you change slop
to 5, you get the document back and a value for max_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