# I cannot search by telephone (part)

**URL:** <https://discuss.elastic.co/t/i-cannot-search-by-telephone-part/333353>\
**Category:** Elasticsearch\
**Created:** [May 13, 2023, 4:23pm UTC](https://discuss.elastic.co/t/i-cannot-search-by-telephone-part/333353 "2023-05-13T16:23:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mg85](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/mg85/32/120987_2.png) [@mg85](https://discuss.elastic.co/u/mg85)\
**Post date:** [May 13, 2023, 4:23pm UTC](https://discuss.elastic.co/t/i-cannot-search-by-telephone-part/333353/1 "2023-05-13T16:23:57Z")

</div>

Im trying to create an autocomplete, this is my index creation:

```auto
curl -X PUT "localhost:9200/backoffice_clients-com" -H 'Content-Type: application/json' -d'
{
  "settings": {
    "analysis": {
      "analyzer": {
        "default": {
          "type": "custom", 
          "tokenizer": "standard",
          "filter": ["lowercase", "asciifolding"]
        }
      }
    }
  },
  "mappings": {
    "_doc": {
      "properties": {
        "id": { "type": "keyword" },
        "backofficeclinic_id": { "type": "keyword" },
        "fullname": { "type": "text" },
        "email": { "type": "text" },
        "idCard": { "type": "text" },
        "telephone": { "type": "text" }
      }
    }
  }
}'

```

and this is my search method

```auto
public function search(string $backofficeclinic_id, string $query): array
{
    $params = [
        'index' => 'backoffice_clients-com',
        'body' => [
            'query' => [
                'bool' => [
                    'must' => [
                        ['term' => ['backofficeclinic_id' => $backofficeclinic_id]],
                        [
                            'multi_match' => [
                                'query' => $query,
                                'type' => 'phrase_prefix',
                                'fields' => ['fullname', 'email', 'idCard', 'telephone']
                            ]
                        ]
                    ]
                ]
            ],
            'sort' => [
                ['_score' => ['order' => 'desc']],
            ],
            'explain' => true, // Add explanation of the scoring
        ]
    ];

    $response = $this->ESclient->search($params);

    foreach ($response['hits']['hits'] as $hit) {
        echo 'Document ID: ', $hit['_id'], PHP_EOL;
        echo 'Score: ', $hit['_score'], PHP_EOL;
        echo 'Explanation: ', json_encode($hit['_explanation']), PHP_EOL;
        echo 'Source: ', json_encode($hit['_source']), PHP_EOL;
    }

    return array_map(function ($hit) {
        return $hit['_source'];
    }, $response['hits']['hits']);
}

```

Im trying with these 2 documents:

```auto
array:2 [
  0 => array:6 [
    "id" => "be7dcc65-1876-4bc1-9a01-dc9183d79e1d"
    "backofficeclinic_id" => "dcf02d56-5240-43fb-9ba0-1ac3eafafa79"
    "fullname" => "Mikel Good"
    "email" => "mikel@gmail.com"
    "idCard" => null
    "telephone" => "+34661422181"
  ]
  1 => array:6 [
    "id" => "816c7cc6-965c-446b-b20f-8f1218757d73"
    "backofficeclinic_id" => "dcf02d56-5240-43fb-9ba0-1ac3eafafa79"
    "fullname" => "Mikel Bad"
    "email" => "mikel@gmail.com"
    "idCard" => "7777"
    "telephone" => "+34661422182"
  ]

```

If I use these keywords:

"mikel" returns 2 documents  
"mikel g" return 1 document (be7dcc65-1876-4bc1-9a01-dc9183d79e1d)  
"mikel b" return 1 document (816c7cc6-965c-446b-b20f-8f1218757d73)

the problem occur when I try to find by using telephone, if I use "661" as keyword, 0 docs are being returned and it should return 2 documents..., I don't know what is need to be changed to fix my code.

Thank you very much for your time.  
Th

---

<div class="post-metadata">

**Author:** ![Priscilla\_Parodi](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/priscilla_parodi/32/43047_2.png) [@Priscilla\_Parodi](https://discuss.elastic.co/u/Priscilla_Parodi)\
**Post date:** [June 7, 2023, 7:21pm UTC](https://discuss.elastic.co/t/i-cannot-search-by-telephone-part/333353/2 "2023-06-07T19:21:37Z")

</div>

Hello @mg85,

You are using a standard tokenizer, so it's dividing the text into terms based on word boundaries. It removes most punctuation symbols. With it, when you perform a full-text search, the terms in the query string can be looked up individually.

Let's consider the `telephone` field.

As you can see here:

```auto
POST _analyze
{
  "analyzer": "standard",
  "text": "+34661422182"
}

```

```auto
{
  "tokens": [
    {
      "token": "34661422182",
      "start_offset": 1,
      "end_offset": 12,
      "type": "<NUM>",
      "position": 0
    }
  ]
}

```

Only one token was created:

`"token": "34661422182"`.

For the full name `"Mikel Good"`:

```auto
POST _analyze
{
  "analyzer": "standard",
  "text": "Mikel Good"
}

```

```auto
{
  "tokens": [
    {
      "token": "mikel",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "good",
      "start_offset": 6,
      "end_offset": 10,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

```

We have two tokens:

`"token": "mikel"`  
`"token": "good"`

In this case, when you search for `"Mikel"` you can find a match. But if it were `"mikelg"` or `"mik"` it wouldn't work.

So, as for your `"telephone"` field you have this `"token": "34661422182"`, it’s similar.

It will work for:

```auto
GET /backoffice_clients-com/_search
{
  "query": {
          "match": {
            "telephone": "34661422182"
          }
  }
}

```

OR

```auto
GET /backoffice_clients-com/_search
{
  "query": {
          "match": {
            "telephone": "+34661422182"
          }
  }
}

```

But not for `"telephone": "3466142218"`.

To solve this, I can think of two options:

1. You can consider using an [Edge n-gram token filter](https://www.elastic.co/guide/en/elasticsearch/reference/8.8/analysis-edgengram-tokenfilter.html#analysis-edgengram-tokenfilter) to produce more tokens by considering a specified length from the beginning of a token.

For example, `"3466142218"` can produce `"3"`, `"34"`, `"346"`, `"3466"` and so on. Then, you can use a simple match query to search for the telephone considering these tokens.

1. Alternatively, you can consider using a [Wildcard query](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html), which would be something like:

```auto
GET /backoffice_clients-com/_search
{
  "query": {
          "wildcard": {
            "telephone": "*661*"
          }
  }
}

```

This allows you to consider other/more characters (\*) before and after the query string.

Hope it helps!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2023, 7:21pm UTC](https://discuss.elastic.co/t/i-cannot-search-by-telephone-part/333353/3 "2023-07-05T19:21:51Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
