# Best practice for prefix search

**URL:** <https://discuss.elastic.co/t/best-practice-for-prefix-search/10019>\
**Category:** Elasticsearch\
**Created:** [December 10, 2012, 4:34pm UTC](https://discuss.elastic.co/t/best-practice-for-prefix-search/10019 "2012-12-10T16:34:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ilya\_Sterin](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/ilya_sterin/32/2585_2.png) [@Ilya\_Sterin](https://discuss.elastic.co/u/Ilya_Sterin)\
**Post date:** [December 10, 2012, 4:34pm UTC](https://discuss.elastic.co/t/best-practice-for-prefix-search/10019/1 "2012-12-10T16:34:54Z")

</div>

We have a need to index a few fields (first name, last name, address, and  
id number). All fields are alphanumeric.

The users will enter terms into an text input. We want to be able to  
search all the fields with a prefix, but giving more preferences to say  
full id number vs partial name.

So say, if someone search for John, there might be 1000 john's in the  
system, but then they start typing an id alphanumeric chars and it starts  
matching partial ids based on prefix matching. When a user enter a full  
id, that should take preference over anything else in the system. I first  
want to make sure I'm approaching the indexing correctly. I'm attaching  
what I have now below. I'm also a bit unsure on what best query strategy  
to use to do this. I believe Prefix query doesn't parse the terms, so it's  
not a good candidate. String query is fine, but requires users to enter  
wildcards. These users will just enter names, city, id, etc... into  
autocomplete input, so I'd don't want to burden them with knowing advanced  
query syntax. I'm sure I need to use a combination and I've tried a bunch,  
from text to string, to prefix and combining them with bool and dis\_max,  
but still haven't quite gotten it. Maybe someone can let me know the best  
strategy to search on multiple fields with user provided terms string  
without requiring them to use wildcards, etc...

I've created an index that does exact as well as edge ngram indexing on  
each field in question. I'm also not sure if this is needed. Isn't just  
an edge ngram enough as long as the max\_ngram covers the longest string you  
care about, or do you still need to include the exact one (for efficiency)?

Here are my setting....

"analysis": {  
"analyzer" : {  
"full\_string":{  
"filter":[  
"standard",  
"lowercase",  
"asciifolding"  
],  
"type":"custom",  
"tokenizer":"standard"  
},  
"prefix\_string":{  
"filter":[  
"standard",  
"lowercase",  
"asciifolding",  
"string\_ngrams"  
],  
"type":"custom",  
"tokenizer":"standard"  
}  
},  
"filter" : {  
"string\_ngrams" : {  
"type" : "edgeNGram",  
"min\_gram" : 2,  
"max\_gram" : 10,  
"side" : 'front'  
}  
}  
}

And here is the mapping

{  
'first\_name': {  
"fields":{  
"first\_name":{  
"type":"string",  
"analyzer":"full\_string"  
},  
"partial":{  
"search\_analyzer":"full\_string",  
"index\_analyzer":"prefix\_string",  
"type":"string"  
}  
},  
"type":"multi\_field"  
},  
'last\_name': {  
"fields":{  
"last\_name":{  
"type":"string",  
"analyzer":"full\_string"  
},  
"partial":{  
"search\_analyzer":"full\_string",  
"index\_analyzer":"prefix\_string",  
"type":"string"  
}  
},  
"type":"multi\_field"  
},  
'city': {  
"fields":{  
"city":{  
"type":"string",  
"analyzer":"full\_string"  
},  
"partial":{  
"search\_analyzer":"full\_string",  
"index\_analyzer":"prefix\_string",  
"type":"string"  
}  
},  
"type":"multi\_field"  
},  
'athlete\_id': {  
"fields":{  
"athlete\_id":{  
"type":"string",  
"analyzer":"full\_string"  
},  
"partial":{  
"search\_analyzer":"full\_string",  
"index\_analyzer":"prefix\_string",  
"type":"string"  
}  
},  
"type":"multi\_field"  
}

--

---

<div class="post-metadata">

**Author:** ![karmi](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/karmi/32/44951_2.png) [@karmi](https://discuss.elastic.co/u/karmi)\
**Post date:** [December 11, 2012, 9:28am UTC](https://discuss.elastic.co/t/best-practice-for-prefix-search/10019/2 "2012-12-11T09:28:16Z")

</div>

Have you looked into using just a `multi_match` query [1](http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query.html) with a  
`match_phrase_prefix` [2](http://www.elasticsearch.org/guide/reference/query-dsl/match-query.html)?

Karel

On Monday, December 10, 2012 5:34:54 PM UTC+1, Ilya Sterin wrote:

> We have a need to index a few fields (first name, last name, address, and  
> id number). All fields are alphanumeric.
> 
> The users will enter terms into an text input. We want to be able to  
> search all the fields with a prefix, but giving more preferences to say  
> full id number vs partial name.
> 
> So say, if someone search for John, there might be 1000 john's in the  
> system, but then they start typing an id alphanumeric chars and it starts  
> matching partial ids based on prefix matching. When a user enter a full  
> id, that should take preference over anything else in the system. I first  
> want to make sure I'm approaching the indexing correctly. I'm attaching  
> what I have now below. I'm also a bit unsure on what best query strategy  
> to use to do this. I believe Prefix query doesn't parse the terms, so it's  
> not a good candidate. String query is fine, but requires users to enter  
> wildcards. These users will just enter names, city, id, etc... into  
> autocomplete input, so I'd don't want to burden them with knowing advanced  
> query syntax. I'm sure I need to use a combination and I've tried a bunch,  
> from text to string, to prefix and combining them with bool and dis\_max,  
> but still haven't quite gotten it. Maybe someone can let me know the best  
> strategy to search on multiple fields with user provided terms string  
> without requiring them to use wildcards, etc...
> 
> I've created an index that does exact as well as edge ngram indexing on  
> each field in question. I'm also not sure if this is needed. Isn't just  
> an edge ngram enough as long as the max\_ngram covers the longest string you  
> care about, or do you still need to include the exact one (for efficiency)?
> 
> Here are my setting....
> 
> "analysis": {  
> "analyzer" : {  
> "full\_string":{  
> "filter":[  
> "standard",  
> "lowercase",  
> "asciifolding"  
> ],  
> "type":"custom",  
> "tokenizer":"standard"  
> },  
> "prefix\_string":{  
> "filter":[  
> "standard",  
> "lowercase",  
> "asciifolding",  
> "string\_ngrams"  
> ],  
> "type":"custom",  
> "tokenizer":"standard"  
> }  
> },  
> "filter" : {  
> "string\_ngrams" : {  
> "type" : "edgeNGram",  
> "min\_gram" : 2,  
> "max\_gram" : 10,  
> "side" : 'front'  
> }  
> }  
> }
> 
> And here is the mapping
> 
> {  
> 'first\_name': {  
> "fields":{  
> "first\_name":{  
> "type":"string",  
> "analyzer":"full\_string"  
> },  
> "partial":{  
> "search\_analyzer":"full\_string",  
> "index\_analyzer":"prefix\_string",  
> "type":"string"  
> }  
> },  
> "type":"multi\_field"  
> },  
> 'last\_name': {  
> "fields":{  
> "last\_name":{  
> "type":"string",  
> "analyzer":"full\_string"  
> },  
> "partial":{  
> "search\_analyzer":"full\_string",  
> "index\_analyzer":"prefix\_string",  
> "type":"string"  
> }  
> },  
> "type":"multi\_field"  
> },  
> 'city': {  
> "fields":{  
> "city":{  
> "type":"string",  
> "analyzer":"full\_string"  
> },  
> "partial":{  
> "search\_analyzer":"full\_string",  
> "index\_analyzer":"prefix\_string",  
> "type":"string"  
> }  
> },  
> "type":"multi\_field"  
> },  
> 'athlete\_id': {  
> "fields":{  
> "athlete\_id":{  
> "type":"string",  
> "analyzer":"full\_string"  
> },  
> "partial":{  
> "search\_analyzer":"full\_string",  
> "index\_analyzer":"prefix\_string",  
> "type":"string"  
> }  
> },  
> "type":"multi\_field"  
> }

--

---

<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 6, 2017, 3:00am UTC](https://discuss.elastic.co/t/best-practice-for-prefix-search/10019/3 "2017-07-06T03:00:23Z")

</div>


