# Query string syntax for exact match against array field?

**URL:** <https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245>\
**Category:** Elasticsearch\
**Created:** [January 15, 2014, 3:44pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245 "2014-01-15T15:44:49Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nikita\_Tovstoles](https://avatars.discourse-cdn.com/v4/letter/n/f17d59/32.png) [@Nikita\_Tovstoles](https://discuss.elastic.co/u/Nikita_Tovstoles)\
**Post date:** [January 15, 2014, 3:44pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/1 "2014-01-15T15:44:49Z")

</div>

suppose we have a type Recipe with field ingredients that stores a JSON  
string array. a couple of Recipe docs' ingredients values may therefore be:

1. ["apples", "oranges]
2. ["apples"]

what query would return docs whose ingredients contain solely "apples"  
(thus only return #2 from the above set)? I thought query string / field  
query[http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html#query-string-syntax)would work but using:  
ingredients:"apples" also returns #1.

Thank you,

-nikita

--  
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).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/7ad78322-803f-4f61-8428-82046dfd8bfb%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/7ad78322-803f-4f61-8428-82046dfd8bfb%40googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![brian\_yoder](https://avatars.discourse-cdn.com/v4/letter/b/f1d935/32.png) [@brian\_yoder](https://discuss.elastic.co/u/brian_yoder)\
**Post date:** [January 15, 2014, 4:05pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/2 "2014-01-15T16:05:36Z")

</div>

One thought occurred to me. Perhaps:

1. Build the token count into your ingredients field. Here's how:  
[http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html#token\_count](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html#token_count)

2a. Pre-analyze your query arguments and remove the duplicates. For  
example, ingredients:"apples" ingredients:"apples".

2b. Add the token\_count to your query, Based on the ES link and on the  
example in 2a, you would add ingredients.word\_count:1 to your query. Now,  
in your set of 2 documents, document #1 would be filtered out of the  
response and only document #2 would be returned.

Hope this helps!

Brian

--  
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).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/041ea39a-f1f0-43c8-a648-f06d614e71ba%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/041ea39a-f1f0-43c8-a648-f06d614e71ba%40googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![Nikita\_Tovstoles](https://avatars.discourse-cdn.com/v4/letter/n/f17d59/32.png) [@Nikita\_Tovstoles](https://discuss.elastic.co/u/Nikita_Tovstoles)\
**Post date:** [January 15, 2014, 7:32pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/3 "2014-01-15T19:32:13Z")

</div>

Thanks, token\_filter worked. Also, w/o modifying mapping, using script  
filter[http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-script-filter.html)query  
worked (query below). However, in both cases, ES seems to treat  
multi-element array and array element with multiple words as having the  
same token count. ie:

1. ["apples", "oranges] //length=2
2. ["apples"] //length=1
3. ["apples and oranges"] //length =3, even with filter query (why not 1)?

...not an issue in my particular use case since all ingredients are 1-word,  
but I would like to understand how to address case #3 above. Write a custom  
Tokenizer?

_Script Filter query:_

{  
"query" : {  
"field": {  
"ingredients": "apples"  
}  
},  
"filter": {  
"script": {  
"script": "doc['ingredients'].values.length == 1"  
}  
}  
}

On Wed, Jan 15, 2014 at 8:05 AM, InquiringMind [brian.from.fl@gmail.com](mailto:brian.from.fl@gmail.com)wrote:

> One thought occurred to me. Perhaps:
> 
> 1. Build the token count into your ingredients field. Here's how:  
> [Elasticsearch Platform — Find real-time answers at scale | Elastic](http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/mapping-core-types.html#token_count)
> 
> 2a. Pre-analyze your query arguments and remove the duplicates. For  
> example, ingredients:"apples" ingredients:"apples".
> 
> 2b. Add the token\_count to your query, Based on the ES link and on the  
> example in 2a, you would add ingredients.word\_count:1 to your query. Now,  
> in your set of 2 documents, document #1 would be filtered out of the  
> response and only document #2 would be returned.
> 
> Hope this helps!
> 
> Brian
> 
> --  
> 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/mvBrfBa5G0Y/unsubscribe](https://groups.google.com/d/topic/elasticsearch/mvBrfBa5G0Y/unsubscribe).  
> To unsubscribe from this group and all its topics, send an email to  
> [elasticsearch+unsubscribe@googlegroups.com](mailto:elasticsearch+unsubscribe@googlegroups.com).  
> To view this discussion on the web visit  
> [https://groups.google.com/d/msgid/elasticsearch/041ea39a-f1f0-43c8-a648-f06d614e71ba%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/041ea39a-f1f0-43c8-a648-f06d614e71ba%40googlegroups.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).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/CAJwaA22aTQ5WDdU358DBJQtUN%2BcM8AOezg9bGNWvCkgx73HBNg%40mail.gmail.com](https://groups.google.com/d/msgid/elasticsearch/CAJwaA22aTQ5WDdU358DBJQtUN%2BcM8AOezg9bGNWvCkgx73HBNg%40mail.gmail.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![brian\_yoder](https://avatars.discourse-cdn.com/v4/letter/b/f1d935/32.png) [@brian\_yoder](https://discuss.elastic.co/u/brian_yoder)\
**Post date:** [January 15, 2014, 8:33pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/4 "2014-01-15T20:33:44Z")

</div>

> 1. ["apples and oranges"] //length =3, even with filter query (why not 1)?
> 
> ...not an issue in my particular use case since all ingredients are  
> 1-word, but I would like to understand how to address case #3 above.

From my experience with querying, ES slurps all values of an array into one  
large set of values and then indexes them. So from a normal matching  
perspective, including phrase matching, the following are equivalent:

"apples and oranges"  
["apples and oranges"]  
["apples" "and" "oranges"]

The big difference is in phrase queries with a position gap between  
individual values. When a position gap is added to a field's mappings, then  
a phase query for a phrase that spans across values requires a slop value  
that is sufficient to cross the gap.

So, for example, consider that a position gap of 4 was added to your  
ingredients field's mapping. Then:

ingredients:"apples and oranges" would match the first two but not the last  
one.  
ingredients:"apples and oranges"~4 would match all of them, including the  
last one.

This implies to me that after the source has been analyzed and indexed, ES  
loses knowledge of the multiple values and knows only of tokens and their  
word positions. Therefore, I am guessing that the mvel length function  
counts the number of tokens, not the number of values in the source JSON.

Brian

--  
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).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/3d95974e-9d78-46e3-a9f9-7a8b3ea3c2aa%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/3d95974e-9d78-46e3-a9f9-7a8b3ea3c2aa%40googlegroups.com).  
For more options, visit [https://groups.google.com/groups/opt\_out](https://groups.google.com/groups/opt_out).

---

<div class="post-metadata">

**Author:** ![brian\_yoder](https://avatars.discourse-cdn.com/v4/letter/b/f1d935/32.png) [@brian\_yoder](https://discuss.elastic.co/u/brian_yoder)\
**Post date:** [January 15, 2014, 10:08pm UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/5 "2014-01-15T22:08:33Z")

</div>

I wonder if this issue[https://github.com/elasticsearch/elasticsearch/issues/4492](https://github.com/elasticsearch/elasticsearch/issues/4492),  
when fixed, will help you by allowing your script to pull values from the  
\_source?

Please feel free to correct me if I'm wrong! Thanks!

Brian

_On Wednesday, January 15, 2014 2:32:13 PM UTC-5, Nikita Tovstoles wrote:_

> _... but I would like to understand how to address case #3 above. Write a  
> custom Tokenizer?_

--  
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).  
To view this discussion on the web visit [https://groups.google.com/d/msgid/elasticsearch/a6318fe8-21a0-4902-a95c-860ca8790bf3%40googlegroups.com](https://groups.google.com/d/msgid/elasticsearch/a6318fe8-21a0-4902-a95c-860ca8790bf3%40googlegroups.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, 1:56am UTC](https://discuss.elastic.co/t/query-string-syntax-for-exact-match-against-array-field/15245/6 "2017-07-06T01:56:36Z")

</div>


