1
votes

I am having difficulty searching for documents by a specific term. Every time I do i get zero results.

Here is a code example:

var customers = new List<SampleCustomer>();
customers.Add(new SampleCustomer(){id=1,firstname="John", surname="Smith", country = "UK", sex = "Male", age=30});
customers.Add(new SampleCustomer(){id=2,firstname="Steve", surname="Jones",  country ="UK", sex = "Male", age=22});
customers.Add(new SampleCustomer(){id=3,firstname="Kate", surname="Smith",  country ="UK", sex = "Female", age=50});
customers.Add(new SampleCustomer(){id=4,firstname="Mark", surname="Jones",  country ="USA", sex = "Male", age=45});
customers.Add(new SampleCustomer(){id=5,firstname="Emma", surname="Jonson",  country ="USA", sex = "Female", age=25});
customers.Add(new SampleCustomer(){id=6,firstname="Tom", surname="Jones",  country ="France", sex = "Male", age=30});
customers.Add(new SampleCustomer(){id=7,firstname="Liz", surname="Web",  country ="France", sex = "Female", age=45});

foreach (var customer in customers)
{
    _elasticClient.DeleteById("sample", "SampleCustomers",customer.id);
    _elasticClient.Index(customer, "sample", "SampleCustomers" , customer.id);
}

using this index I can query the customers with the first name of smith using the query string filter

var queryByQueryString = _elasticClient.Search<SampleCustomer>(s =>
           s.From(0).Size(10).Type("SampleCustomers")
           .Query(q => q.QueryString(qs => qs.Query("Smith").OnField("surname"))));

but if I try search for customers using the term filer I get zero results

var queryByTerm = _elasticClient.Search<SampleCustomer>(s =>
            s.From(0).Size(10).Type("SampleCustomers")
            .Query(q => q.Term(p => p.surname, "Smith")));

I dont know what im doing wrong? In the example above I want to make sure that my query only returns results where the surname exactly equals "Smith" and that if someone had a double-barrelled surname such as "Smith Jones" they would not appear in the results.

1

1 Answers

6
votes

It's hard to know for sure without seeing your mapping, but your problem might just be case-sensitivity. If the "surname" field is using the default standard analyzer (which it is unless you specified one in the mapping), the tokens are modified to lower-case. So there will be a "smith" token but no "Smith". When you use a query string query, your query text will be analyzed (with the standard analyzer unless you provide one) and so the search text gets modified to "smith" which matches a token. But a term filter does NOT do any analysis, and the filter text "Smith" does not match any tokens so no results are returned.

If this is indeed your problem, then this should return results:

var queryByTerm = _elasticClient.Search<SampleCustomer>(s =>
            s.From(0).Size(10).Type("SampleCustomers")
            .Query(q => q.Term(p => p.surname, "smith")));

Alternatively, you could set the "surname" field to "index": "not_analyzed" in your mapping (will require a re-index), and so tokens will not be lower-cased, and your term filter with the text "Smith" will match.