0

I have problem with my queries when I'm using " or ' - then I expect match_phrase, but I don't know how I can retrieve posts when I'm using match_phrase with & For example I'm using Something & Something as phrase, and when I'm didn't using ' and " I can see posts with Something & Something but there I'm using multi_match.

Something what I've tried:

{
"from": 0,
"size": 10,
"sort": {
    "post_date": {
        "order": "desc"
    }
},
"query": {
    "function_score": {
        "query": {
            "bool": {
                "must": [
                    {
                        "match_phrase": {
                            "query": "Something & Something"
                        }
                    }
                ]
            }
        },
        "exp": {
            "post_date_gmt": {
                "scale": "270d",
                "decay": 0.5,
                "offset": "90d"
            }
        },
        "score_mode": "avg",
        "boost_mode": "sum"
    }
},
"post_filter": {
    "bool": {
        "must": [
            {
                "terms": {
                    "post_type.raw": [
                        "post"
                    ]
                }
            },
            {
                "terms": {
                    "post_status": [
                        "publish"
                    ]
                }
            }
        ]
    }
}
}

But this doesn't return any post, and returning hits total 0. Anyone have any idea, or suggestions, what I'm doing wrong ?

Jakub Jóźwiak
  • 57
  • 1
  • 10

1 Answers1

1

match_phrase is very restrictive and in most of cases is recommended to use it inside a should clause to increase the score instead of a must, because it requires the user to type the value exactly as it is.

Example document

POST test_jakub/_doc
{
  "query": "Something & Something",
  "post_type": {
    "raw": "post"
  },
  "post_status": "publish",
  "post_date_gmt": "2021-01-01T12:10:30Z",
  "post_date": "2021-01-01T12:10:30Z"
}

With this document searching for "anotherthing Something & Something" will return no results, that's why is a bad idea to use match_phrase here.

You can take 2 approaches

  1. If you need this kind of tight queries take a look to the slop parameter that adds some flexibility to the match_phrase query allowing omit or transpose words in the phrase

  2. Switch to a regular match query (recommended). In most cases this will work fine, but if you want to do extra score to the phrase matches you can add it as a should clause.

POST test_jakub/_search
{
  "from": 0,
  "size": 10,
  "sort": {
    "post_date": {
      "order": "desc"
    }
  },
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [
            {
              "match_phrase": {
                "query": {
                  "query": "anotherthing something & something",
                  "slop": 2
                }
              }
            }
          ],
          "must": [
            {
              "match": {
                "query": "anotherthing something & something"
              }
            }
          ]
        }
      },
      "exp": {
        "post_date_gmt": {
          "scale": "270d",
          "decay": 0.5,
          "offset": "90d"
        }
      },
      "score_mode": "avg",
      "boost_mode": "sum"
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "terms": {
            "post_type.raw": [
              "post"
            ]
          }
        },
        {
          "terms": {
            "post_status": [
              "publish"
            ]
          }
        }
      ]
    }
  }
}

Last advice is to avoid using "query" as field name because leads to confusion and will break Kibana autocomplete on Dev Tools.

llermaly
  • 2,331
  • 2
  • 16
  • 29