I am trying to build a dynamic query using NEST which is as under
string product = "goldpgl";
string agencyid = "1123";
ISearchResponse <ProductModel> res = client().Search<ProductModel>(s => s
.Index("proddata")
.From(0)
.Size(100)
.Query(q =>
+q.Term(p => p.product, product) &&
+q.Term(p => p.agencyid, agencyid)));
If I pass, product value = "GoldPGL"
[ N.B.~ Real value in the index ], I am not able to find the result.
However, if I pass the value in lowercase like "goldpgl", it works.
Also, it does not work for values like "Gold - PGL" or "SOME OTHER LOAN".
My POCO is as under
public class ProductModel
{
public string product { get; set; }
public string agencyid { get; set; }
}
What is wrong and how to rectify this?
As you have not provided the mapping and search query, I am assuming its happening because you are using the term query not the match query.
Term queries are not analyzed means whatever you entered in your search query would be matched against the tokens in the index. And by default, all the text fields in Elasticsearch use the standard analyzer which converts tokens to lowercase. hence GoldPGL
doesn't match while goldpgl
matches in your term query.
While match
query as explained the official document is analyzed query and the same analyzer is applied on the search term, which is applied at index time, hence GoldPGL
as well as goldpgl
converted to goldpgl
and both the query matches the documents and same is with Gold - PGL
which also matches and verifies by me.
Analyze API comes very handy to troubleshoot these types of issue, where search query doesn't match the indexed tokens and one example of how GOLDPGL
would be analyzed is shown below:
POST /_analyze
{
"text": "GOLDPGL",
"analyzer" : "standard"
}
{ "token": "goldpgl",}
{
"text": "GOLD - PGL",
"analyzer" : "standard"
}
{
"token": "gold",
"start_offset": 0,
"end_offset": 4,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "pgl",
"start_offset": 7,
"end_offset": 10,
"type": "<ALPHANUM>",
"position": 1
}
I reproduced your issue and as I am not familiar with NEST, showing your example using the REST API.
POST /
{
"mappings": {
"properties": {
"product": {
"type": "text"
}
}
}
}
Index some documents
POST //_doc/1
{
"product": "GoldPGL"
}
Index 2nd doc
{
"product": "Gold - PGL"
}
GoldPGL
is used){
"query": {
"term": {
"product": {
"value": "GoldPGL"
}
}
}
}
goldgpl
, it gives result{
"query": {
"term": {
"product": {
"value": "goldpgl"
}
}
}
}
"hits": [
{
"_index": "so-term-nest",
"_type": "_doc",
"_id": "1",
"_score": 0.8025915,
"_source": {
"product": "GoldPGL"
}
}
]
{
"query": {
"match" : {
"product" : {
"query" : "GoldPGL"
}
}
}
}
and this return results
"hits": [
{
"_index": "so-term-nest",
"_type": "_doc",
"_id": "1",
"_score": 0.8025915,
"_source": {
"product": "GoldPGL"
}
}
]