# Cookbook Entry - Case insensitive array search

**URL:** <https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780>\
**Category:** Elasticsearch\
**Created:** [May 21, 2012, 3:25am UTC](https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780 "2012-05-21T03:25:41Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![James\_Cook\_3](https://avatars.discourse-cdn.com/v4/letter/j/d2c977/32.png) [@James\_Cook\_3](https://discuss.elastic.co/u/James_Cook_3)\
**Post date:** [May 21, 2012, 3:25am UTC](https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780/1 "2012-05-21T03:25:41Z")

</div>

This is actually a legitimate request for help from the group, but I am  
writing it as a cookbook entry with the thought that it could eventually  
make its way into a cookbook section of the elasticsearch website which  
could be the basis for some user documentation to supplement the reference  
documentation that currently exists. I would like the group to do a few  
things:

1. Correct any bad descriptions. Be picky about terminology.
2. Offer alternative solutions
3. Offer up any other comments

Once the example is accurate and alternatives are vetted, this example  
could then be added to a pull request for a cookbook section of the site.  
\*  
\*  
_Overview_

A JSON object may include an array of strings by which it will need to be  
queried. This string array may be a list of tags assigned to a blog post,  
or in our example a list of roles assigned to a user. For our example, we  
want to supply multiple roles and return a hit if any of the roles supplied  
matches the roles assigned to the user. Oh yeah, we don't want to consider  
case when performing our search.

_Setup_

Because we want case insensitivity in our search, we have to initialize a  
custom analyzer for the roles field. The custom analyzer,  
"lowercase\_keyword" is defined in the elasticsearch.yml file.

index :  
analysis :  
analyzer :  
lowercase\_keyword :  
type : custom  
tokenizer : keyword  
filter : [lowercase]

Create the index and add the mapping file:

curl -XPOST localhost:9200/cookbook -d '{  
"mappings" : {  
"profiles" : {  
"properties" : {  
"username":{"type": "string", "index": "not\_analyzed"},  
"roles":{"type": "string", "index": "analyzed",  
"analyzer":"lowercase\_keyword"}  
}  
}  
}  
}'

_Test Data_

curl -XPUT 'localhost:9200/cookbook/profiles/1' -d '  
{ "username" : "fred", "roles" : ["ROLE\_ADMIN"] }'  
curl -XPUT 'localhost:9200/cookbook/profiles/2' -d '  
{ "username" : "wilma", "roles" : ["ROLE\_WIFE"] }'  
curl -XPUT 'localhost:9200/cookbook/profiles/3' -d '  
{ "username" : "barney", "roles" : ["ROLE\_USER"] }'  
curl -XPUT 'localhost:9200/cookbook/profiles/4' -d '  
{ "username" : "betty", "roles" : ["ROLE\_WIFE","role\_user"] }'

_Querying_

Because of the case insensitive use case, our search must be a query and  
our criteria must be analyzed by the same lowercase\_keyword tokenizer by  
which our documents were indexed.

_Example 1_  
curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
{  
"query": {  
"field": {  
"roles": "role\_wife"  
}  
}  
}'

This satisfies a query for a single role, however multiple roles will have  
to be conjoined using an OR clause.

_Example 2_  
curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
{  
"query": {  
"field": {  
"roles": "role\_admin OR role\_USER"  
}  
}  
}'

_Filtering_

If we were to permit ourselves some pre-processing of the search criteria,  
we can simulate the results of a query using a straight filter approach.  
The following filter provides the same results as in Example 2 above.  
However, the search criteria must be lowercased in order to match the case  
for the respective terms that have been processed with the  
lowercase\_keyword analyzer.

_Example 3_  
curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
{  
"query":{  
"constant\_score":{  
"filter":{  
"or":[  
{ "term": { "roles" : "role\_admin" } },  
{ "term": { "roles" : "role\_user" } }  
]  
}  
}  
}  
}'

---

<div class="post-metadata">

**Author:** ![kimchy](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/kimchy/32/44952_2.png) [@kimchy](https://discuss.elastic.co/u/kimchy)\
**Post date:** [May 23, 2012, 9:07pm UTC](https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780/2 "2012-05-23T21:07:39Z")

</div>

Looks great!, I would add also a sample of how to configure the analyzer  
also as part of the create index request.

On Mon, May 21, 2012 at 5:25 AM, James Cook [jcook@pykl.com](mailto:jcook@pykl.com) wrote:

> This is actually a legitimate request for help from the group, but I am  
> writing it as a cookbook entry with the thought that it could eventually  
> make its way into a cookbook section of the elasticsearch website which  
> could be the basis for some user documentation to supplement the reference  
> documentation that currently exists. I would like the group to do a few  
> things:
> 
> 1. Correct any bad descriptions. Be picky about terminology.
> 2. Offer alternative solutions
> 3. Offer up any other comments
> 
> Once the example is accurate and alternatives are vetted, this example  
> could then be added to a pull request for a cookbook section of the site.  
> \*  
> \*  
> _Overview_
> 
> A JSON object may include an array of strings by which it will need to be  
> queried. This string array may be a list of tags assigned to a blog post,  
> or in our example a list of roles assigned to a user. For our example, we  
> want to supply multiple roles and return a hit if any of the roles supplied  
> matches the roles assigned to the user. Oh yeah, we don't want to consider  
> case when performing our search.
> 
> _Setup_
> 
> Because we want case insensitivity in our search, we have to initialize a  
> custom analyzer for the roles field. The custom analyzer,  
> "lowercase\_keyword" is defined in the elasticsearch.yml file.
> 
> index :  
> analysis :  
> analyzer :  
> lowercase\_keyword :  
> type : custom  
> tokenizer : keyword  
> filter : [lowercase]
> 
> Create the index and add the mapping file:
> 
> curl -XPOST localhost:9200/cookbook -d '{  
> "mappings" : {  
> "profiles" : {  
> "properties" : {  
> "username":{"type": "string", "index": "not\_analyzed"},  
> "roles":{"type": "string", "index": "analyzed",  
> "analyzer":"lowercase\_keyword"}  
> }  
> }  
> }  
> }'
> 
> _Test Data_
> 
> curl -XPUT 'localhost:9200/cookbook/profiles/1' -d '  
> { "username" : "fred", "roles" : ["ROLE\_ADMIN"] }'  
> curl -XPUT 'localhost:9200/cookbook/profiles/2' -d '  
> { "username" : "wilma", "roles" : ["ROLE\_WIFE"] }'  
> curl -XPUT 'localhost:9200/cookbook/profiles/3' -d '  
> { "username" : "barney", "roles" : ["ROLE\_USER"] }'  
> curl -XPUT 'localhost:9200/cookbook/profiles/4' -d '  
> { "username" : "betty", "roles" : ["ROLE\_WIFE","role\_user"] }'
> 
> _Querying_
> 
> Because of the case insensitive use case, our search must be a query and  
> our criteria must be analyzed by the same lowercase\_keyword tokenizer by  
> which our documents were indexed.
> 
> _Example 1_  
> curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> {  
> "query": {  
> "field": {  
> "roles": "role\_wife"  
> }  
> }  
> }'
> 
> This satisfies a query for a single role, however multiple roles will have  
> to be conjoined using an OR clause.
> 
> _Example 2_  
> curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> {  
> "query": {  
> "field": {  
> "roles": "role\_admin OR role\_USER"  
> }  
> }  
> }'
> 
> _Filtering_
> 
> If we were to permit ourselves some pre-processing of the search criteria,  
> we can simulate the results of a query using a straight filter approach.  
> The following filter provides the same results as in Example 2 above.  
> However, the search criteria must be lowercased in order to match the case  
> for the respective terms that have been processed with the  
> lowercase\_keyword analyzer.
> 
> _Example 3_  
> curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> {  
> "query":{  
> "constant\_score":{  
> "filter":{  
> "or":[  
> { "term": { "roles" : "role\_admin" } },  
> { "term": { "roles" : "role\_user" } }  
> ]  
> }  
> }  
> }  
> }'

---

<div class="post-metadata">

**Author:** ![James\_Cook\_3](https://avatars.discourse-cdn.com/v4/letter/j/d2c977/32.png) [@James\_Cook\_3](https://discuss.elastic.co/u/James_Cook_3)\
**Post date:** [May 24, 2012, 12:05am UTC](https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780/3 "2012-05-24T00:05:11Z")

</div>

Perhaps someone with more experience updating the site could issue a pull  
request for a cookbook section? Perhaps these could be some sections?

- Configuration
  - OS
  - Java
  - Elasticsearch

- Mapping
- Index
- Query and Filter
- Facets
- Percolator
- Integration
  - Amazon
  - RabbitMQ
  - MongoDB
  - Rivers

Then it's just a matter of working our way backward through the group  
messages to add a cookbook entry for each Q&A type posting. Heck, if you  
just search for Clinton's posts ([Redirecting to Google Groups](http://goo.gl/TJHcq)) you'll end up with  
hundreds of good cookbook candidates.

Jim Cook  
[jcook@pykl.com](mailto:jcook@pykl.com)

Pykl Studios [http://pykl.com/](http://pykl.com/)  
1000 Creekside Plaza  
Gahanna, OH 43230  
phone +1 614 398 3636tollfree +1 855 FOR PYKLskype jcook.pyklgtalk  
[jcook@pykl.com](mailto:jcook@pykl.com)

On Wed, May 23, 2012 at 5:07 PM, Shay Banon [kimchy@gmail.com](mailto:kimchy@gmail.com) wrote:

> Looks great!, I would add also a sample of how to configure the analyzer  
> also as part of the create index request.
> 
> On Mon, May 21, 2012 at 5:25 AM, James Cook [jcook@pykl.com](mailto:jcook@pykl.com) wrote:
> 
> > This is actually a legitimate request for help from the group, but I am  
> > writing it as a cookbook entry with the thought that it could eventually  
> > make its way into a cookbook section of the elasticsearch website which  
> > could be the basis for some user documentation to supplement the reference  
> > documentation that currently exists. I would like the group to do a few  
> > things:
> > 
> > 1. Correct any bad descriptions. Be picky about terminology.
> > 2. Offer alternative solutions
> > 3. Offer up any other comments
> > 
> > Once the example is accurate and alternatives are vetted, this example  
> > could then be added to a pull request for a cookbook section of the site.  
> > \*  
> > \*  
> > _Overview_
> > 
> > A JSON object may include an array of strings by which it will need to be  
> > queried. This string array may be a list of tags assigned to a blog post,  
> > or in our example a list of roles assigned to a user. For our example, we  
> > want to supply multiple roles and return a hit if any of the roles supplied  
> > matches the roles assigned to the user. Oh yeah, we don't want to consider  
> > case when performing our search.
> > 
> > _Setup_
> > 
> > Because we want case insensitivity in our search, we have to initialize a  
> > custom analyzer for the roles field. The custom analyzer,  
> > "lowercase\_keyword" is defined in the elasticsearch.yml file.
> > 
> > index :  
> > analysis :  
> > analyzer :  
> > lowercase\_keyword :  
> > type : custom  
> > tokenizer : keyword  
> > filter : [lowercase]
> > 
> > Create the index and add the mapping file:
> > 
> > curl -XPOST localhost:9200/cookbook -d '{  
> > "mappings" : {  
> > "profiles" : {  
> > "properties" : {  
> > "username":{"type": "string", "index": "not\_analyzed"},  
> > "roles":{"type": "string", "index": "analyzed",  
> > "analyzer":"lowercase\_keyword"}  
> > }  
> > }  
> > }  
> > }'
> > 
> > _Test Data_
> > 
> > curl -XPUT 'localhost:9200/cookbook/profiles/1' -d '  
> > { "username" : "fred", "roles" : ["ROLE\_ADMIN"] }'  
> > curl -XPUT 'localhost:9200/cookbook/profiles/2' -d '  
> > { "username" : "wilma", "roles" : ["ROLE\_WIFE"] }'  
> > curl -XPUT 'localhost:9200/cookbook/profiles/3' -d '  
> > { "username" : "barney", "roles" : ["ROLE\_USER"] }'  
> > curl -XPUT 'localhost:9200/cookbook/profiles/4' -d '  
> > { "username" : "betty", "roles" : ["ROLE\_WIFE","role\_user"] }'
> > 
> > _Querying_
> > 
> > Because of the case insensitive use case, our search must be a query and  
> > our criteria must be analyzed by the same lowercase\_keyword tokenizer by  
> > which our documents were indexed.
> > 
> > _Example 1_  
> > curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> > {  
> > "query": {  
> > "field": {  
> > "roles": "role\_wife"  
> > }  
> > }  
> > }'
> > 
> > This satisfies a query for a single role, however multiple roles will  
> > have to be conjoined using an OR clause.
> > 
> > _Example 2_  
> > curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> > {  
> > "query": {  
> > "field": {  
> > "roles": "role\_admin OR role\_USER"  
> > }  
> > }  
> > }'
> > 
> > _Filtering_
> > 
> > If we were to permit ourselves some pre-processing of the search  
> > criteria, we can simulate the results of a query using a straight filter  
> > approach. The following filter provides the same results as in Example 2  
> > above. However, the search criteria must be lowercased in order to match  
> > the case for the respective terms that have been processed with the  
> > lowercase\_keyword analyzer.
> > 
> > _Example 3_  
> > curl -XPOST 'localhost:9200/cookbook/profiles/\_search' -d '  
> > {  
> > "query":{  
> > "constant\_score":{  
> > "filter":{  
> > "or":[  
> > { "term": { "roles" : "role\_admin" } },  
> > { "term": { "roles" : "role\_user" } }  
> > ]  
> > }  
> > }  
> > }  
> > }'

---

<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:27am UTC](https://discuss.elastic.co/t/cookbook-entry-case-insensitive-array-search/7780/4 "2017-07-06T03:27:21Z")

</div>


