Search code examples
elasticsearchampersand

How to search for an ampersand in Elasticsearch?


In Elasticsearch, how to search for a value with an ampersand? Tried:

http://localhost:9200/my_index/_search?q=name:"procter \u0026 gamble"

Solution

  • There are various ways but one way would be to declare your string as not_analyzed in your mapping (see below) and then search for the exact value that has been indexed.

    curl -XPUT localhost:9200/tests -d '{
      "mappings": {
        "test": {
          "properties": {
            "name": {
              "type": "string",
              "fields": {
                "raw": {
                  "type": "string",
                  "index": "not_analyzed"
                }
              }
            }
          }
        }
      }
    }'
    

    Now we index a sample document:

    curl -XPUT localhost:9200/tests/test/1 -d '{"name":"procter & gamble"}'
    

    And finally, your search query will return the document you expect:

    curl -XGET localhost:9200/tests/test/_search?q=name.raw:"procter %26 gamble"
    

    UPDATE Here is another more involved way using an nGram tokenizer which will index all the possible tokens of length 2 to 20 (arbitrary choice) of your names.

    curl -XPUT localhost:9200/tests -d '{
      "settings": {
        "analysis": {
          "analyzer": {
            "ngram_analyzer": {
              "tokenizer": "ngram_tokenizer",
              "filter": [
                "lowercase"
              ]
            }
          },
          "tokenizer": {
            "ngram_tokenizer": {
              "type": "nGram",
              "min_gram": 2,
              "max_gram": 20
            }
          }
        }
      },
      "mappings": {
        "test": {
          "properties": {
            "name": {
              "type": "string",
              "index_analyzer": "ngram_analyzer",
              "search_analyzer": "keyword"
            }
          }
        }
      }
    }'
    

    Then you can search for the exact name like before

    curl -XGET localhost:9200/tests/test/_search?q=name:"procter %26 gamble"
    

    Or simply by some token present in your name

    curl -XGET localhost:9200/tests/test/_search?q=name:procter
    curl -XGET localhost:9200/tests/test/_search?q=name:"procter %26"
    curl -XGET localhost:9200/tests/test/_search?q=name:gamble