2

My Product name: Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio

Search Term: "5600" or "Epson 5600"

In the above condition, my elasticsearch is not able to search "5600". It returns empty products.

I was using solr in my Magento 1 and it was working fine.

Any suggestions on this?

1 Answer 1

1

You know your data better than Elasticsearch. In order to retrieve great output you will have to plan your indices ahead.

    DELETE /products
    # create index containing one document
    PUT /products/_doc/1
    {
        "product": "Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio"
    }
    # let's search for a portion of a string-token
    GET products/_search
    {
      "query": {
        "match": {
          "product": "5600" 
        }
      }
    }
    # noting found!

    # how is our field mapped?
    GET /products/_mapping
    # no analyzer specified => standard is utilized.
    # standard tokenizer is used by default
    GET /_analyze
    {
      "tokenizer" : "standard",
      "text" : "Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio"
    }
    # there is no token for '5600' and there will be no hits.

    # The standard tokenizer will not do. We need a different tokenizer!
    # it's up to you to decide the tokens.
    GET /_analyze
    {
      "tokenizer": {
        "type": "ngram",
        "min_gram": 3,
        "max_gram": 3,
        "token_chars": [
          "letter",
          "digit"
        ]
      },
      "text": "Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio"
    }

    # we cannot change properties of an index if there are documents. Index has to go.
    DELETE /products
    # create index with custom analyzer and field-mapping
    PUT products
    {
      "settings": {
        "analysis": {
          "analyzer": {
            "my_analyzer": {
              "tokenizer": "my_tokenizer"
            }
          },
          "tokenizer": {
            "my_tokenizer": {
              "type": "ngram",
              "min_gram": 3,
              "max_gram": 3,
              "token_chars": [
                "letter",
                "digit"
              ]
            }
          }
        }
      },
      "mappings": {
        "_doc": {
          "properties": {
            "product": {
              "type": "text",
              "analyzer": "my_analyzer"
            }
          }
        }
      }
    }
    # create document
    PUT /products/_doc/1
    {
        "product": "Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio"
    }
    # how is our field mapped?
    GET /products/_mapping
    # 'my_analyzer' is utilized

    # let's search for a portion of a string-token
    GET products/_search
    {
      "query": {
        "match": {
          "product": "560" 
        }
      }
    }

    # document found!

    # anything containing '560' (3 letters) will be a hit.
    # '56' will not hit.
    # 'anything-before-560-anything-after' will be a hit!

    # tokens produced.
    POST products/_analyze
    {
      "analyzer": "my_analyzer",
      "text" : "Epson EH TW5600 Full HD Home Cinema Projector | Lens Shift | 2500 Lumens | Bluetooth Audio"
    }
1
  • 1
    I am still learning elastic search. I know about ngram, but have to implement it magento way. Any suggestions on that? Commented Dec 26, 2019 at 3:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.