Alireza Mazochi
Alireza Mazochi

Reputation: 977

Query Match For Integer Number In Elastic Search With Laravel

I followed this article for connecting laravel and ElasticSearch: https://madewithlove.be/how-to-integrate-your-laravel-app-with-elasticsearch/

I have a table in MySQL database that it has tree field:"title","description" and "price". "title" and "description is string type. so I write below code for searching and this worked correctly:

private function searchOnElasticsearch(string $query): array
{
    $instance = new Article;

    $items = $this->search->search([
        'index' => $instance->getSearchIndex(),
        'type' => $instance->getSearchType(),
        'body' => [
            'query' => [
                'multi_match' => [
                    'fields' => ['title', 'description'],
                    'query' => $query,
                ],
            ],
        ],
    ]);

    return $items;
}

But now, I need to check "price" field that is a bigInt type like two other field: 'fields' => ['title', 'description','price'],

UPDATE

When I add "price" to field I get this error in laravel:

{"error":{"root_cause":[{"type":"query_shard_exception","reason":"failed to create query: {\n \"multi_match\" : {\n \"query\" : \"bad\",\n \"fields\" : [\n \"description^1.0\",\n \"price^1.0\",\n \"tags^1.0\",\n \"title^1.0\"\n ],\n \"type\" : \"best_fields\",\n \"operator\" : \"OR\",\n \"slop\" : 0,\n \"prefix_length\" : 0,\n \"max_expansions\" : 50,\n \"zero_terms_query\" : \"NONE\",\n \"auto_generate_synonyms_phrase_query\" : true,\n \"fuzzy_transpositions\" : true,\n \"boost\" : 1.0\n }\n}","index_uuid":"mm787GxMS4WjjjqwRD5YIw","index":"commodities"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"commodities","node":"JYWiIdbLQtu3aWkm_F-e9Q","reason":{"type":"query_shard_exception","reason":"failed to create query: {\n \"multi_match\" : {\n \"query\" : \"bad\",\n \"fields\" : [\n \"description^1.0\",\n \"price^1.0\",\n \"tags^1.0\",\n \"title^1.0\"\n ],\n \"type\" : \"best_fields\",\n \"operator\" : \"OR\",\n \"slop\" : 0,\n \"prefix_length\" : 0,\n \"max_expansions\" : 50,\n \"zero_terms_query\" : \"NONE\",\n \"auto_generate_synonyms_phrase_query\" : true,\n \"fuzzy_transpositions\" : true,\n \"boost\" : 1.0\n }\n}","index_uuid":"mm787GxMS4WjjjqwRD5YIw","index":"commodities","caused_by":{"type":"number_format_exception","reason":"For input string: \"bad\""}}}]},"status":400}

Upvotes: 0

Views: 2812

Answers (1)

Val
Val

Reputation: 217544

I suggest something like this, i.e. split the query into two parts, one for text fields and another for numeric fields. However, only add the match on numeric fields if the $query is indeed a number:

$body = [
    'query' => [
        'bool' => [
            'should' => [
                [
                   'multi_match' => [
                       'fields' => ['title', 'description'],
                       'query' => $query
                   ]
                ]
            ]
        ]
    ]
];

// if the query is numeric add an additional clause for the price field
if (is_numeric($query)) {
    $body['query']['bool']['should'][] = [ 'match' => [ 'price' => $query]];
}

$items = $this->search->search([
    'index' => $instance->getSearchIndex(),
    'type' => $instance->getSearchType(),
    'body' => $body
]);

Upvotes: 2

Related Questions