devlord
devlord

Reputation: 4164

Nest Elasticsearch wildcard query works as querystring but not with fluent API

I have about a hundred test documents in my index, built using NBuilder:

[
  {
    "title" : "Title1",
    "text" : "Text1"
  },
  {
    "title" : "Title2",
    "text" : "Text2"
  },
  {
    "title" : "Title3",
    "text" : "Text3"
  }
]

I want to query them with a wildcard to find all items with "text" starts with "Text". But when I use two wildcard methods in Nest I get two different results.

var response = await client.SearchAsync<FakeFile>(s => s.Query(q => q
    .QueryString(d => d.Query("text:Text*")))
    .From((page - 1) * pageSize)
    .Size(pageSize));

This returns 100 results. But I'm trying to use a fluent API rather than querystring.

var response = await client.SearchAsync<FakeFile>(s => s
    .Query(q => q
        .Wildcard(c => c
            .Field(f => f.Text)
            .Value("Text*"))));

This returns 0 results. I'm new to Elasticsearch. I've tried to make the example as simple as possible to make sure I understand it piece-by-piece. I don't know why nothing is returning from the second query. Please help.

Upvotes: 1

Views: 1442

Answers (2)

Rob
Rob

Reputation: 9979

Assuming your text field is of type text, then during indexing elasticsearch will store Text1 as text1 internally in the inverted index. Exactly the same analysis will happen when using query string query, but not when you are using wildcard query.

.QueryString(d => d.Query("text:Text*"))) looks for text* and .Wildcard(c => c.Field(f => f.Text).Value("Text*"))) looks for Text* but elasticsearch stores internally only first one.

Hope that helps.

Upvotes: 1

Assael Azran
Assael Azran

Reputation: 2993

Supposed your mapping looks like that:

{
  "mappings": {
    "doc": {
      "properties": {
        "title": {
          "type": "text"
        },
        "text":{
          "type": "text"
        }
      }
    }
  }
}

Try this (Value should be in lowercase):

var response = await client.SearchAsync<FakeFile>(s => s
.Query(q => q
    .Wildcard(c => c
        .Field(f => f.Text)
        .Value("text*"))));

Or this (don't know if f.Text has text property on it):

var response = await client.SearchAsync<FakeFile>(s => s
.Query(q => q
    .Wildcard(c => c
        .Field("text")
        .Value("text*"))));

Kibana syntax:

GET index/_search
{
  "query": {
    "wildcard": {
      "text": {
        "value": "text*"
      }
    }
  }
}

Upvotes: 1

Related Questions