9

I am building a query to Elastic 5 (using nest in .net), i am trying to achive this result:

Must have value1 and value 2

Should have value3 or value 4

and should have value5 or value6

Here is my query:

    {
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "code": {
              "query": "value1"
            }
          }
        },
        {
          "match": {
            "code": {
              "query": "value2"
            }
          }
        }
      ],
      "should": [
        {
          "match": {
            "code": {
              "query": "value3"
            }
          }
        },
        {
          "match": {
            "code": {
              "query": "value4"
            }
          }
        }
        ],
        "should": [
        {
          "match": {
            "code": {
              "query": "value5"
            }
          }
        },
        {
          "match": {
            "code": {
              "query": "value6"
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

I dont get the desired answer (for example i dont have anywhere value 5 and value 6 but still getting results)

Thank you

IB.
  • 1,019
  • 3
  • 13
  • 21
  • You can only have one one `should` clause in your bool query. In my opinion, one of your should clauses is getting dismissed. Why not putting all `should` matches in a single `should` clause? – Val Nov 13 '16 at 13:38
  • Since i need either value3 or value4 AND either value5 or value6 – IB. Nov 13 '16 at 13:42

3 Answers3

25

Then you need something like this:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "code": {
              "query": "value1"
            }
          }
        },
        {
          "match": {
            "code": {
              "query": "value2"
            }
          }
        },
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "match": {
                  "code": {
                    "query": "value3"
                  }
                }
              },
              {
                "match": {
                  "code": {
                    "query": "value4"
                  }
                }
              }
            ]
          }
        },
        {
          "bool": {
            "minimum_should_match": 1,
            "should": [
              {
                "match": {
                  "code": {
                    "query": "value5"
                  }
                }
              },
              {
                "match": {
                  "code": {
                    "query": "value6"
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
Val
  • 207,596
  • 13
  • 358
  • 360
10

Here's the NEST equivalent of Val's answer

void Main()
{
    var client = new ElasticClient();

    client.Search<MyDocument>(s => s
        .Query(q => q
            .Bool(b => b
                .Must(mu => mu
                    .Match(m => m
                        .Field(f => f.Code)
                        .Query("value1")
                    ), mu  => mu
                    .Match(m => m
                        .Field(f => f.Code)
                        .Query("value2")
                    ), mu => mu
                    .Bool(bb => bb
                        .MinimumShouldMatch(1)
                        .Should(sh => sh
                            .Match(m => m
                                .Field(f => f.Code)
                                .Query("value3")
                            ), sh => sh
                            .Match(m => m
                                .Field(f => f.Code)
                                .Query("value4")
                            )
                        )
                    ), mu => mu
                    .Bool(bb => bb
                        .MinimumShouldMatch(1)
                        .Should(sh => sh
                            .Match(m => m
                                .Field(f => f.Code)
                                .Query("value5")
                            ), sh => sh
                            .Match(m => m
                                .Field(f => f.Code)
                                .Query("value6")
                            )
                        )
                    )
                )
            )
        )
    );
}

public class MyDocument
{
    public string Code { get; set; }
}
Community
  • 1
  • 1
Russ Cam
  • 124,184
  • 33
  • 204
  • 266
0

Here's another example using more concrete sample data:

{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "author": {
              "query": "Anita Author"
            }
          }
        },
        {
          "match": {
            "author": {
              "query": "Bertha Booster"
            }
          }
        }
      ],
      "should": 
      [
          {
            "match": {
              "title": {
                "query": "A Fantastic Book"
              }
            }
          },
        {
          "match": {
            "title": {
              "query": "A Fantastic Book, Volume 2"
            }
          }
        },
        {
          "match": {
            "title": {
              "query": "Yet Another Fantastic Book"
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}
rotarydial
  • 2,181
  • 2
  • 23
  • 27