# Text Search with more preference to prefix matches

**URL:** <https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388>\
**Category:** Elasticsearch\
**Created:** [January 17, 2013, 10:24am UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388 "2013-01-17T10:24:37Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![0xff](https://avatars.discourse-cdn.com/v4/letter/0/5fc32e/32.png) [@0xff](https://discuss.elastic.co/u/0xff)\
**Post date:** [January 17, 2013, 10:24am UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/1 "2013-01-17T10:24:37Z")

</div>

Started to work on elasticsearch recently and it has been an interesting  
couple of months.

I have Indexed few documents in elasticsearch. Each document has got fields  
like username, biography, post, interests etc. I want to do a text search  
for 'Smith' in all the indexed fields with the field 'username' starting  
with Smith ranking higher than the partial match on the 'username' field  
and on other fields like post, interests etc.

I am using grails and I have given higher boost for username but I want the  
document with username 'Smith' ranked higher than the document with  
username 'Joe Smith' or other fields having prefix or partial matches. How  
do i approach this issue? Thanks.

--

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 18, 2013, 5:35pm UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/2 "2013-01-18T17:35:41Z")

</div>

You should get this automatically unless you set omit\_norms to true in your  
mappings.

In general, if you want to boost a certain types of matches without  
affecting the set of results that you are getting back, you can use Custom  
Filters Score Query[http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html](http://www.elasticsearch.org/guide/reference/query-dsl/custom-filters-score-query.html)  
.

On Thursday, January 17, 2013 5:24:37 AM UTC-5, Sara wrote:

> Started to work on elasticsearch recently and it has been an interesting  
> couple of months.
> 
> I have Indexed few documents in elasticsearch. Each document has got  
> fields like username, biography, post, interests etc. I want to do a text  
> search for 'Smith' in all the indexed fields with the field 'username'  
> starting with Smith ranking higher than the partial match on the 'username'  
> field and on other fields like post, interests etc.
> 
> I am using grails and I have given higher boost for username but I want  
> the document with username 'Smith' ranked higher than the document with  
> username 'Joe Smith' or other fields having prefix or partial matches. How  
> do i approach this issue? Thanks.

--

---

<div class="post-metadata">

**Author:** ![Clinton\_Gormley](https://avatars.discourse-cdn.com/v4/letter/c/50afbb/32.png) [@Clinton\_Gormley](https://discuss.elastic.co/u/Clinton_Gormley)\
**Post date:** [January 18, 2013, 5:38pm UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/3 "2013-01-18T17:38:04Z")

</div>

On Fri, 2013-01-18 at 09:35 -0800, Igor Motov wrote:

> You should get this automatically unless you set omit\_norms to true in  
> your mappings.

Unfortunately, the norm is stored in a single byte, and so loses  
granularity when dealing with very short strings like a username. The  
difference between "smith" and "john smith" is too small for norms to  
make a difference

clint

> In general, if you want to boost a certain types of matches without  
> affecting the set of results that you are getting back, you can use  
> Custom Filters Score Query.
> 
> On Thursday, January 17, 2013 5:24:37 AM UTC-5, Sara wrote:  
> Started to work on elasticsearch recently and it has been an  
> interesting couple of months.
> 
> ```
> I have Indexed few documents in elasticsearch. Each document
> has got fields like username, biography, post, interests etc.
> I want to do a text search for 'Smith' in all the indexed
> fields with the field 'username' starting with Smith ranking
> higher than the partial match on the 'username' field and on
> other fields like post, interests etc.
>     
>     
> I am using grails and I have given higher boost for username
> but I want the document with username 'Smith' ranked higher
> than the document with username 'Joe Smith' or other fields
> having prefix or partial matches. How do i approach this
> issue? Thanks.
> 
> ```
> 
> --

--

---

<div class="post-metadata">

**Author:** ![Igor\_Motov](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/igor_motov/32/45193_2.png) [@Igor\_Motov](https://discuss.elastic.co/u/Igor_Motov)\
**Post date:** [January 18, 2013, 6:46pm UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/4 "2013-01-18T18:46:48Z")

</div>

Yes, clint is right here, if you have very large index time boost set for  
this field, it can really skew the norms. So, you it might be also useful  
to switch to query time boosting.

On Friday, January 18, 2013 12:38:04 PM UTC-5, Clinton Gormley wrote:

> On Fri, 2013-01-18 at 09:35 -0800, Igor Motov wrote:
> 
> > You should get this automatically unless you set omit\_norms to true in  
> > your mappings.
> 
> Unfortunately, the norm is stored in a single byte, and so loses  
> granularity when dealing with very short strings like a username. The  
> difference between "smith" and "john smith" is too small for norms to  
> make a difference
> 
> clint
> 
> > In general, if you want to boost a certain types of matches without  
> > affecting the set of results that you are getting back, you can use  
> > Custom Filters Score Query.
> > 
> > On Thursday, January 17, 2013 5:24:37 AM UTC-5, Sara wrote:  
> > Started to work on elasticsearch recently and it has been an  
> > interesting couple of months.
> > 
> > ```
> > I have Indexed few documents in elasticsearch. Each document 
> > has got fields like username, biography, post, interests etc. 
> > I want to do a text search for 'Smith' in all the indexed 
> > fields with the field 'username' starting with Smith ranking 
> > higher than the partial match on the 'username' field and on 
> > other fields like post, interests etc. 
> >     
> >     
> > I am using grails and I have given higher boost for username 
> > but I want the document with username 'Smith' ranked higher 
> > than the document with username 'Joe Smith' or other fields 
> > having prefix or partial matches. How do i approach this 
> > issue? Thanks. 
> > 
> > ```
> > 
> > --

--

---

<div class="post-metadata">

**Author:** ![egaumer](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/egaumer/32/2365_2.png) [@egaumer](https://discuss.elastic.co/u/egaumer)\
**Post date:** [January 19, 2013, 2:58pm UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/5 "2013-01-19T14:58:14Z")

</div>

If I understand correctly, you want exact matches on the username field to  
be ranked higher than partial matches on username or matches on any other  
fields.

What about indexing username twice, using two different tokenizers? One  
that splits on whitespace and one that does not. Then if you want to boost  
exact matches on username you can use a DisMaxQuery to give a higher boost  
when the username is an exact match.

ejs.Request()  
.indices(['index1', 'index2'])  
.types(['type1', 'type2'])  
.query(  
ejs.DisMaxQuery()  
.queries(ejs.MatchQuery('post', 'Smith'))  
.queries(ejs.MatchQuery('biography', 'Smith'))  
.queries(ejs.MatchQuery('interests', 'Smith'))  
.queries(ejs.MatchQuery('username', 'Smith')  
.boost(2))  
.queries(ejs.MatchQuery('username\_exact', 'Smith')  
.boost(4)))

This example can be extended/modified if you want to boost prefix matches  
(e.g., by using PrefixQuery or SpanFirstQuery rather than MatchQuery).  
Ultimately, I think you'll need to leverage DisMaxQuery.

On Thursday, January 17, 2013 5:24:37 AM UTC-5, Sara wrote:

> Started to work on elasticsearch recently and it has been an interesting  
> couple of months.
> 
> I have Indexed few documents in elasticsearch. Each document has got  
> fields like username, biography, post, interests etc. I want to do a text  
> search for 'Smith' in all the indexed fields with the field 'username'  
> starting with Smith ranking higher than the partial match on the 'username'  
> field and on other fields like post, interests etc.
> 
> I am using grails and I have given higher boost for username but I want  
> the document with username 'Smith' ranked higher than the document with  
> username 'Joe Smith' or other fields having prefix or partial matches. How  
> do i approach this issue? Thanks.

--

---

<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, 2:55am UTC](https://discuss.elastic.co/t/text-search-with-more-preference-to-prefix-matches/10388/6 "2017-07-06T02:55:33Z")

</div>


