0

I'm attempting to create an Elasticsearch query in NEST which uses the Bool query, but everything I put inside the Bool method seems to get ignored.

This is the code I've tried:

var query = "my query";
var fileType = "Poster";
var searchResults = _client.Search<Doc>(s => 
        s.Query(q =>
            q.Bool(
                b => b.Must(
                    m =>  m.MatchPhrase(mp =>
                        mp.Query(query).Fuzziness(2))
                    ).Must(m => m.Match(
                        mp => mp.Query(fileType))))
            ).Highlight(x =>
                    x.OnFields(y =>
                        y.OnField(f => f.File)
                         .PreTags("<strong>")
                         .PostTags("</strong>"))
            ).Fields("fileType", "title"));

Here is the JSON request NEST is generating from that code. Notice that it's missing the entire query property:

{
  "highlight": {
    "fields": {
      "file": {
        "pre_tags": [
          "<strong>"
        ],
        "post_tags": [
          "</strong>"
        ]
      }
    }
  },
  "fields": [
    "fileType",
    "title"
  ]
}

I tried taking out the extra highlighting and field selection, in case that was causing a problem, just leaving the Query and the Bool:

var searchResults = _client.Search<Doc>(s => 
        s.Query(q =>
            q.Bool(
                b => b.Must(
                    m =>  m.MatchPhrase(mp =>
                        mp.Query(query).Fuzziness(2))
                    )
                .Must(m => m.Match(mp => mp.Query(fileType))))
            ));

This code generates an empty JSON object.

I couldn't find mention of the Bool and Must methods in the NEST documentation and I haven't been able to figure it out with trial and error.

What am I doing wrong?


Notes

I have used NEST's Query method with a simple QueryString. It generated the expected JSON request, so I'm pretty sure the way I have things configured is correct.

This is the JSON query that I'm attempting to recreate with NEST:

{
  "fields": [
    "title",
    "fileType"
  ],
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "fileType": {
              "query": "Poster"
            }
          }
        },
        {
          "match_phrase": {
            "file": {
              "query": "my query",
              "fuzziness": 2
            }
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "file": {}
    }
  }
}
Sam
  • 4,994
  • 4
  • 30
  • 37

1 Answers1

5

Your queries are missing .OnField(f => f.YourField). NEST ignores such queries because of conditionless.

I hope it's clear right now.

update

You should change your query to something like this:

var searchResults = client.Search<Doc>(s => s
    .Query(q => q
        .Bool(b => b
            .Must(
                m => m.Match(mp => mp.OnField(f => f.YourField).Query(fileType)),
                m => m.MatchPhrase(mp => mp.OnField(f => f.YourField).Query(query).Fuzziness(2)))
                ))
    .Highlight(x => x
        .OnFields(y => y
            .OnField(f => f.File)
            .PreTags("<strong>")
            .PostTags("</strong>")))
    .Fields("fileType", "title"));

You should use .Must(..) only once in bool query, otherwise you will replace previous .Must(..) definition. Fortunately you can pass multiple queries into the .Must(..) method.

Rob
  • 9,664
  • 3
  • 41
  • 43
  • Thanks, it's working for the Match clause, but MatchPhrase is still being ignored (even when I use it by itself). Any idea why that might be? – Sam Aug 13 '15 at 16:47
  • 1
    I would just like to add that in 6.x version you must use Field method instead of OnField in the Match clause. – BineG May 23 '18 at 10:38