skip to Main Content

In my program, the user can "disable" fuzzy searching on the front-end. This changes the back-end request to the following:

$query['query']['bool']['must'][] = [
    'bool' => [
        'should' => [
            ['match_phrase' => ['name' => $param]],
            ['match_phrase' => ['description' => $param]],
        ],
        'minimum_should_match' => 1,
    ],
];

The $param is the search query. The document I am looking to hit is Evo-Singularity.

The following is my hits on this:

evo => works

evo- => works

evo-sing => no results

singularity => works

With that in mind, I’ve tried changing to a wildcard approach:

$param = '*'.$param.'*';
//No Fuzzy Search - Do a literal match
$query['query']['bool']['must'][] = [
    'wildcard' => [
         'name' => $param
    ],
    'wildcard' => [
         'description' => $param
    ],                
];

evo => works

evo- => no results

evo-sing => no results

singularity => no results

Then I went to the console to try see if I could find it:

This works:

{
  "query": {
    "match": {
      "name": "evo-singularity"
    }
  }
}

None of these wildcard searches work:

{
  "query": {
    "wildcard": {
      "name": {
        "value": "*evo\-singularity*",
        "boost": 1.0,
        "rewrite": "constant_score"
      }
    }
  }
}

or

{
  "query": {
    "wildcard": {
      "name": {
        "value": "*evo*singularity*",
        "boost": 1.0,
        "rewrite": "constant_score"
      }
    }
  }
}

But this does work:

{
  "query": {
    "wildcard": {
      "name": {
        "value": "*singularity*",
        "boost": 1.0,
        "rewrite": "constant_score"
      }
    }
  }
}

Here is the actual document in elasticsearch. I’ve removed all unnecessary information:

"_source": {
          "type": "Trap Card",
          "description": "Target 1 "Evoltile" monster and 1 "Evolsaur" monster in your Graveyard; Special Summon 1 "Evolzar" Xyz Monster from your Extra Deck, and if you do, attach those monsters to it as Xyz Materials.",
          "name": "Evo-Singularity",
        },

At this stage, I’m out of ideas. Documents that have space hyphen space seem to work without issue:

vanquish soul - kaiser

But documents that have no space around the hyphens have issue:

evo-singularity

My analyzer settings:

{
  "card_database": {
    "settings": {
      "index": {
        "provided_name": "card_database",
        "number_of_replicas": "1",
        "max_result_window": "15000",
        "uuid": "Jfgh8F_FQQO21qSkQDngFw",
        "number_of_shards": "1",
        "analysis": {
          "filter": {
            "my_stopwords_filter": {
              "stopwords": [
                "a",
                "an",
                "the"
              ],
              "type": "stop"
            }
          },
          "analyzer": {
            "my_analyzer": {
              "filter": [
                "lowercase",
                "my_stopwords_filter"
              ],
              "tokenizer": "standard"
            }
          }
        },
        "creation_date": "1676906459467",
        "version": {
          "created": "8060199"
        },
        "routing": {
          "allocation": {
            "include": {
              "_tier_preference": "data_content"
            }
          }
        },
        "blocks": {
          "read_only_allow_delete": "false"
        }
      }
    }
  }
}

Here is a link to my mappings:

https://justpaste.it/471fi

2

Answers


  1. If the field is indexed as a keyword try to change the query to a term query

    Login or Signup to reply.
  2. TLDR;

    It seems like you don’t want to be using a match_phrase type of query but a match_phrase_prefix query.
    As in the doc:

    Like the match query but used for matching exact phrases or word proximity matches.

    The extact phrases makes me think this is not what you want in the case of evo-sing.

    Solution

    You may switch to a match_phrase_prefix query instead:

    GET /75694329/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "match_phrase_prefix": {
                      "name": "evo"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
    

    To reproduce

    I use elasticsearch 8.6.2

    Set up:

    PUT /75694329/_doc/1
    {
      "name": "evo-singularity"
    }
    

    Notes

    Although you have provided an analyser in your question.
    You are not using it on the name field, so I used the standard analyzer.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search