# Best implementation of a multi-field, multi-term prefix query

**URL:** <https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725>\
**Category:** Elasticsearch\
**Created:** [July 9, 2013, 5:24pm UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725 "2013-07-09T17:24:21Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Paul\_Bellora](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_bellora/32/74372_2.png) [@Paul\_Bellora](https://discuss.elastic.co/u/Paul_Bellora)\
**Post date:** [July 9, 2013, 5:24pm UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725/1 "2013-07-09T17:24:21Z")

</div>

I'm just getting started with ES and its Java API. As a proof-of-concept I  
implemented a generic search method that takes user-inputted text and does  
prefix matching against various fields:

List searchFoos(@Nullable String phrase) {

```
final QueryBuilder queryBuilder;
if (phrase != null && !phrase.isEmpty()) {
    
    phrase = phrase.trim().toLowerCase();
    
    final BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

    for (final String term : phrase.split("\\s+")) {
        boolQueryBuilder
                .should(QueryBuilders.prefixQuery("name", term))
                .should(QueryBuilders.prefixQuery("slogan", term))
                .should(QueryBuilders.prefixQuery("affiliation", term))
                .should(QueryBuilders.prefixQuery("tags", term));
    }
    
    queryBuilder = boolQueryBuilder;
}
else {
    queryBuilder = QueryBuilders.matchAllQuery();
}

//etc.

```

}

This is obviously a pretty naive implementation. I'd like to improve it  
with respect to two overlapping concerns:

- I'd like to use some kind of multi-match on the various fields instead  
of tacking prefix queries onto the bool one after the other. I know there  
is multi\_match[http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/)  
and match\_phrase\_prefix[http://www.elasticsearch.org/guide/reference/query-dsl/match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/match-query/),  
but I couldn't find any documentation or examples of a multi\_  
match\_phrase\_prefix.
- I'd like to avoid manually splitting on whitespace and attaching  
queries for each individual token. match\_phrase\_prefix seems to offer a  
solution here again, but it wasn't clear to me how similar it is to  
regular prefix[http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/](http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/).  
I do understand that match\_phrase\_prefix only "allows for prefix matches  
on the last term in the text" - so this would be different behavior than  
what I have currently, which allows for prefix matches on any term in the  
text.

My questions are:

- How can I best improve the above implementation while keeping the same  
behavior?
- If there is indeed something like multi\_match\_phrase\_prefix, where is  
its documentation, or else helpful examples?
- As I noted, match\_phrase\_prefix will behave differently from a prefix  
query for each term of the phrase - is that a more typical implementation  
for the use case of a search bar for a user? This is a really common use  
case so I'm wondering what queries others have used and why.

Paul

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![javanna](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/javanna/32/4698_2.png) [@javanna](https://discuss.elastic.co/u/javanna)\
**Post date:** [July 16, 2013, 9:59am UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725/2 "2013-07-16T09:59:50Z")

</div>

Hi Paul,  
the multi\_match query supports all the options that are supported by the  
match query. That means that you can execute a phrase\_prefix on multiple  
fields with a single query like the following:

{  
"query" : {  
"multi\_match" : {  
"fields" : ["title", "subtitle"],  
"query" : "trying out ela",  
"type" : "phrase\_prefix"  
}  
}  
}

Using a match phrase prefix would use only the last term as a prefix, thus  
like you said it's quite different compared to using a prefix query for  
each term. On the other hand, this makes sense when it comes to  
auto-complete queries as you type and should be more performant too.

Cheers,  
Luca

On Tuesday, July 9, 2013 7:24:21 PM UTC+2, Paul Bellora wrote:

> I'm just getting started with ES and its Java API. As a proof-of-concept I  
> implemented a generic search method that takes user-inputted text and does  
> prefix matching against various fields:
> 
> List searchFoos(@Nullable String phrase) {
> 
> ```
> final QueryBuilder queryBuilder;
> if (phrase != null && !phrase.isEmpty()) {
>     
> phrase = phrase.trim().toLowerCase();
>     
> final BoolQueryBuilder boolQueryBuilder = 
> 
> ```
> 
> QueryBuilders.boolQuery();
> 
> ```
> for (final String term : phrase.split("\\s+")) {
> boolQueryBuilder
> .should(QueryBuilders.prefixQuery("name", term))
> .should(QueryBuilders.prefixQuery("slogan", term))
> .should(QueryBuilders.prefixQuery("affiliation", term
> 
> ```
> 
> ))  
> .should(QueryBuilders.prefixQuery("tags", term));  
> }
> 
> ```
> queryBuilder = boolQueryBuilder;
> }
> else {
> queryBuilder = QueryBuilders.matchAllQuery();
> }
> 
> //etc.
> 
> ```
> 
> }
> 
> This is obviously a pretty naive implementation. I'd like to improve it  
> with respect to two overlapping concerns:
> 
> - I'd like to use some kind of multi-match on the various fields  
> instead of tacking prefix queries onto the bool one after the other. I know  
> there is multi\_match[http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/)  
> and match\_phrase\_prefix[http://www.elasticsearch.org/guide/reference/query-dsl/match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/match-query/),  
> but I couldn't find any documentation or examples of a multi\_  
> match\_phrase\_prefix.
> - I'd like to avoid manually splitting on whitespace and attaching  
> queries for each individual token. match\_phrase\_prefix seems to offer  
> a solution here again, but it wasn't clear to me how similar it is to  
> regular prefix[http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/](http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/).  
> I do understand that match\_phrase\_prefix only "allows for prefix  
> matches on the last term in the text" - so this would be different behavior  
> than what I have currently, which allows for prefix matches on any term in  
> the text.
> 
> My questions are:
> 
> - How can I best improve the above implementation while keeping the  
> same behavior?
> - If there is indeed something like multi\_match\_phrase\_prefix, where  
> is its documentation, or else helpful examples?
> - As I noted, match\_phrase\_prefix will behave differently from a  
> prefix query for each term of the phrase - is that a more typical  
> implementation for the use case of a search bar for a user? This is a  
> really common use case so I'm wondering what queries others have used and  
> why.
> 
> Paul

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![Paul\_Bellora](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_bellora/32/74372_2.png) [@Paul\_Bellora](https://discuss.elastic.co/u/Paul_Bellora)\
**Post date:** [July 17, 2013, 7:37pm UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725/3 "2013-07-17T19:37:22Z")

</div>

Hi Lucas,

Thanks for clearing up my confusion with your helpful example - I'd  
forgotten to look at using the "type" property. Good point about the  
auto-complete queries - I think it does make sense for a "type ahead"  
situation, but I'll probably still look at using prefix matching on each  
term for full-fledged search results. Like I said, I'm interested to hear  
about what's been successful in other people's experience and why.

On Tue, Jul 16, 2013 at 5:59 AM, Luca Cavanna [cavannaluca@gmail.com](mailto:cavannaluca@gmail.com) wrote:

> Hi Paul,  
> the multi\_match query supports all the options that are supported by the  
> match query. That means that you can execute a phrase\_prefix on multiple  
> fields with a single query like the following:
> 
> {  
> "query" : {  
> "multi\_match" : {  
> "fields" : ["title", "subtitle"],  
> "query" : "trying out ela",  
> "type" : "phrase\_prefix"  
> }  
> }  
> }
> 
> Using a match phrase prefix would use only the last term as a prefix, thus  
> like you said it's quite different compared to using a prefix query for  
> each term. On the other hand, this makes sense when it comes to  
> auto-complete queries as you type and should be more performant too.
> 
> Cheers,  
> Luca
> 
> On Tuesday, July 9, 2013 7:24:21 PM UTC+2, Paul Bellora wrote:
> 
> > I'm just getting started with ES and its Java API. As a proof-of-concept  
> > I implemented a generic search method that takes user-inputted text and  
> > does prefix matching against various fields:
> > 
> > List searchFoos(@Nullable String phrase) {
> > 
> > ```
> > final QueryBuilder queryBuilder;
> > if (phrase != null && !phrase.isEmpty()) {
> > 
> > phrase = phrase.trim().**toLowerCase();
> > 
> > final BoolQueryBuilder boolQueryBuilder =
> > 
> > ```
> > 
> > QueryBuilders.boolQuery();
> > 
> > ```
> > for (final String term : phrase.split("\\**s+")) {
> > boolQueryBuilder
> > .should(QueryBuilders.**prefixQuery("name", term))
> > .should(QueryBuilders.**prefixQuery("slogan", term))
> > .should(QueryBuilders.**prefixQuery("affiliation",
> > 
> > ```
> > 
> > ter\*\*m))  
> > .should(QueryBuilders.\*\*prefixQuery("tags", term));  
> > }
> > 
> > ```
> > queryBuilder = boolQueryBuilder;
> > }
> > else {
> > queryBuilder = QueryBuilders.matchAllQuery();
> > }
> > 
> > //etc.
> > 
> > ```
> > 
> > }
> > 
> > This is obviously a pretty naive implementation. I'd like to improve it  
> > with respect to two overlapping concerns:
> > 
> > - I'd like to use some kind of multi-match on the various fields  
> > instead of tacking prefix queries onto the bool one after the other. I know  
> > there is multi\_match[http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/)  
> > and match\_\*\*phrase\_prefix[http://www.elasticsearch.org/guide/reference/query-dsl/match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/match-query/),  
> > but I couldn't find any documentation or examples of a multi\_  
> > match\_phrase\_prefix.
> > - I'd like to avoid manually splitting on whitespace and attaching  
> > queries for each individual token. match\_phrase\_prefix \*\*seems to  
> > offer a solution here again, but it wasn't clear to me how similar it is  
> > to regular prefix[http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/](http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/).  
> > I do understand that match\_phrase\_prefix only "allows for prefix  
> > matches on the last term in the text" - so this would be different behavior  
> > than what I have currently, which allows for prefix matches on any term in  
> > the text.
> > 
> > My questions are:
> > 
> > - How can I best improve the above implementation while keeping the  
> > same behavior?
> > - If there is indeed something like multi\_match\_phrase\_prefix\*\*,  
> > where is its documentation, or else helpful examples?
> > - As I noted, match\_phrase\_prefix will behave differently from a  
> > prefix query for each term of the phrase - is that a more typical  
> > implementation for the use case of a search bar for a user? This is a  
> > really common use case so I'm wondering what queries others have used and  
> > why.
> > 
> > Paul
> 
> --  
> You received this message because you are subscribed to a topic in the  
> Google Groups "elasticsearch" group.  
> To unsubscribe from this topic, visit  
> [https://groups.google.com/d/topic/elasticsearch/VoJiZf2x\_28/unsubscribe](https://groups.google.com/d/topic/elasticsearch/VoJiZf2x_28/unsubscribe).  
> To unsubscribe from this group and all its topics, send an email to  
> [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
> For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![Paul\_Bellora](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/paul_bellora/32/74372_2.png) [@Paul\_Bellora](https://discuss.elastic.co/u/Paul_Bellora)\
**Post date:** [July 17, 2013, 7:39pm UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725/4 "2013-07-17T19:39:06Z")

</div>

And I should say Luca! Sorry for the typo.

On Wed, Jul 17, 2013 at 3:37 PM, Paul Bellora [bellorap@gmail.com](mailto:bellorap@gmail.com) wrote:

> Hi Lucas,
> 
> Thanks for clearing up my confusion with your helpful example - I'd  
> forgotten to look at using the "type" property. Good point about the  
> auto-complete queries - I think it does make sense for a "type ahead"  
> situation, but I'll probably still look at using prefix matching on each  
> term for full-fledged search results. Like I said, I'm interested to hear  
> about what's been successful in other people's experience and why.
> 
> On Tue, Jul 16, 2013 at 5:59 AM, Luca Cavanna [cavannaluca@gmail.com](mailto:cavannaluca@gmail.com)wrote:
> 
> > Hi Paul,  
> > the multi\_match query supports all the options that are supported by the  
> > match query. That means that you can execute a phrase\_prefix on multiple  
> > fields with a single query like the following:
> > 
> > {  
> > "query" : {  
> > "multi\_match" : {  
> > "fields" : ["title", "subtitle"],  
> > "query" : "trying out ela",  
> > "type" : "phrase\_prefix"  
> > }  
> > }  
> > }
> > 
> > Using a match phrase prefix would use only the last term as a prefix,  
> > thus like you said it's quite different compared to using a prefix query  
> > for each term. On the other hand, this makes sense when it comes to  
> > auto-complete queries as you type and should be more performant too.
> > 
> > Cheers,  
> > Luca
> > 
> > On Tuesday, July 9, 2013 7:24:21 PM UTC+2, Paul Bellora wrote:
> > 
> > > I'm just getting started with ES and its Java API. As a proof-of-concept  
> > > I implemented a generic search method that takes user-inputted text and  
> > > does prefix matching against various fields:
> > > 
> > > List searchFoos(@Nullable String phrase) {
> > > 
> > > ```
> > > final QueryBuilder queryBuilder;
> > > if (phrase != null && !phrase.isEmpty()) {
> > > 
> > > phrase = phrase.trim().**toLowerCase();
> > > 
> > > final BoolQueryBuilder boolQueryBuilder =
> > > 
> > > ```
> > > 
> > > QueryBuilders.boolQuery();
> > > 
> > > ```
> > > for (final String term : phrase.split("\\**s+")) {
> > > boolQueryBuilder
> > > .should(QueryBuilders.**prefixQuery("name", term))
> > > .should(QueryBuilders.**prefixQuery("slogan", term))
> > > .should(QueryBuilders.**prefixQuery("affiliation",
> > > 
> > > ```
> > > 
> > > ter\*\*m))  
> > > .should(QueryBuilders.\*\*prefixQuery("tags", term));  
> > > }
> > > 
> > > ```
> > > queryBuilder = boolQueryBuilder;
> > > }
> > > else {
> > > queryBuilder = QueryBuilders.matchAllQuery();
> > > }
> > > 
> > > //etc.
> > > 
> > > ```
> > > 
> > > }
> > > 
> > > This is obviously a pretty naive implementation. I'd like to improve it  
> > > with respect to two overlapping concerns:
> > > 
> > > - I'd like to use some kind of multi-match on the various fields  
> > > instead of tacking prefix queries onto the bool one after the other. I know  
> > > there is multi\_match[http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/multi-match-query/)  
> > > and match\_\*\*phrase\_prefix[http://www.elasticsearch.org/guide/reference/query-dsl/match-query/](http://www.elasticsearch.org/guide/reference/query-dsl/match-query/),  
> > > but I couldn't find any documentation or examples of a multi\_  
> > > match\_phrase\_prefix.
> > > - I'd like to avoid manually splitting on whitespace and attaching  
> > > queries for each individual token. match\_phrase\_prefix \*\*seems to  
> > > offer a solution here again, but it wasn't clear to me how similar it is  
> > > to regular prefix[http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/](http://www.elasticsearch.org/guide/reference/query-dsl/prefix-query/).  
> > > I do understand that match\_phrase\_prefix only "allows for prefix  
> > > matches on the last term in the text" - so this would be different behavior  
> > > than what I have currently, which allows for prefix matches on any term in  
> > > the text.
> > > 
> > > My questions are:
> > > 
> > > - How can I best improve the above implementation while keeping the  
> > > same behavior?
> > > - If there is indeed something like multi\_match\_phrase\_prefix\*\*,  
> > > where is its documentation, or else helpful examples?
> > > - As I noted, match\_phrase\_prefix will behave differently from a  
> > > prefix query for each term of the phrase - is that a more typical  
> > > implementation for the use case of a search bar for a user? This is a  
> > > really common use case so I'm wondering what queries others have used and  
> > > why.
> > > 
> > > Paul
> > 
> > --  
> > You received this message because you are subscribed to a topic in the  
> > Google Groups "elasticsearch" group.  
> > To unsubscribe from this topic, visit  
> > [https://groups.google.com/d/topic/elasticsearch/VoJiZf2x\_28/unsubscribe](https://groups.google.com/d/topic/elasticsearch/VoJiZf2x_28/unsubscribe).  
> > To unsubscribe from this group and all its topics, send an email to  
> > [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
> > For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

--  
You received this message because you are subscribed to the Google Groups "elasticsearch" group.  
To unsubscribe from this group and stop receiving emails from it, send an email to [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<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:25am UTC](https://discuss.elastic.co/t/best-implementation-of-a-multi-field-multi-term-prefix-query/12725/5 "2017-07-06T02:25:52Z")

</div>


