Search code examples
phpelasticsearchelasticsearch-analyzers

elasticsearch php not return search result without space


I have added 15k records in elasticsearch index products_idx1 and type product.

In records product name like apple iphone 6 so when I search for iphone6 it returns empty data.

Here is my code in php elasticsearch

<?php

    use Elasticsearch\ClientBuilder;

    require 'vendor/autoload.php';

   $client = ClientBuilder::create()->build();
 $values =['name','name.prefix','name.suffix','sku'];
$params =
[
'client'=>['verify'=>1,'connect_timeout'=>5],
'from'=> 0,
'size'=>25,
 'body'  =>[
'query' => [
 'bool'=>
            [
            'should'=> [[
                'multi_match'=> ['query'=>'iphone6','type'=>'cross_fields','fields'=>$values,'operator'=>'OR']
                ],
                ['match'=>['all'=>['query'=>'iphone6','operator'=>'OR','fuzziness'=>'AUTO'] ]]
                ]
            ]

],
'sort'=>['_score'=>['order'=>'desc']],
],

'index'=>'products_idx1'
];

 $response = $client->search($params);
echo "<pre>";print_r($response);

Solution

  • Using the shingle and pattern_replace token filter it's possible to get the result for all 3 search terms which is mentioned in question and comment aka iphone, iphone6 and appleiphone and below is complete example of it.

    As explained in the comment, you search time tokens generated from search term should match the index time tokens generated from indexed doc, in order to get the search result and this is what I've achieved by creating the custom analyzer.

    Index mapping

    {
      "settings": {
        "analysis": {
          "analyzer": {
            "text_analyzer": {
              "tokenizer": "standard",
              "filter": [
                "shingle",
                "lowercase",
                "space_filter"
              ]
            }
          },
          "filter": {
            "space_filter": {
              "type": "pattern_replace",
              "pattern": " ",
              "replacement": "",
              "preserve_original": true
            }
          }
        }
      },
      "mappings": {
        "properties": {
          "title": {
            "type": "text",
            "analyzer": "text_analyzer"
          }
        }
      }
    }
    

    Index your sample doc

    {
      "title" : "apple iphone 6" 
    }
    

    Search query of appleiphone with result

    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "title": "appleiphone"
              }
            }
          ]
        }
      }
    }
    

    result

    "hits": [
          {
            "_index": "ana",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.3439677,
            "_source": {
              "title": "apple iphone 6",
              "title_normal": "apple iphone 6"
            }
          }
        ]
    

    Search query for iphone6 with result

    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "title": "iphone6"
              }
            }
          ]
        }
      }
    }
    

    Result

     "hits": [
          {
            "_index": "ana",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.3439677,
            "_source": {
              "title": "apple iphone 6",
              "title_normal": "apple iphone 6"
            }
          }
        ]
    

    And Last but not the least search query for iphone

    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "title": "iphone"
              }
            }
          ]
        }
      }
    }
    

    Result

    "hits": [
          {
            "_index": "ana",
            "_type": "_doc",
            "_id": "1",
            "_score": 0.3439677,
            "_source": {
              "title": "apple iphone 6",
              "title_normal": "apple iphone 6"
            }
          }
        ]