# How to make a specific edgeNGram query

**URL:** <https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524>\
**Category:** Elasticsearch\
**Created:** [October 6, 2011, 4:59am UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524 "2011-10-06T04:59:47Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Neil1](https://avatars.discourse-cdn.com/v4/letter/n/278dde/32.png) [@Neil1](https://discuss.elastic.co/u/Neil1)\
**Post date:** [October 6, 2011, 4:59am UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/1 "2011-10-06T04:59:47Z")

</div>

I have the following index

curl -XPUT '[http://localhost:9200/test/](http://localhost:9200/test/)' -d '{  
"settings": {  
"number\_of\_shards": 1,  
"number\_of\_replicas": 0  
},

```
"analysis": {
    "analyzer": {
        "containsText" : {
           "tokenizer": "whitespace",
           "filter": ["asciifolding", "lowercase", "autocomplete"]
        }
     },
    "filter": {
        "autocomplete": {"type": "edgeNGram", "min_gram": "1",

```

"max\_gram": "100", "side": "front"}  
}  
},

```
"mappings": {
    "program" : {
        "properties" : {
            "title": {"type" : "string", "store" : "yes",

```

"index" : "analyzed" , "term\_vector" : "with\_positions\_offsets",  
"analyzer" : "containsText"}  
}  
}  
}  
}'

curl -XPUT [http://localhost:9200/test/program/1652094](http://localhost:9200/test/program/1652094) -d '{  
"title": "James Franco"  
}'

So my question is why does this return a result?

curl -XGET [http://localhost:9200/test/program/\_search](http://localhost:9200/test/program/_search) -d '{  
"query" : {  
"queryString" : {  
"default\_field" : "title",  
"query" : "james i",  
"analyzer" : "containsText"  
}  
}  
}'

I don't want it to since it doesn't match on the last name. What do I  
need to change to get my expected result?  
I would like to have my query string analyzed the same way as my  
indexed string.

If it helps -- I was able to do this is solr as such:

```
  <fieldType name="containsText" class="solr.TextField"

```

positionIncrementGap="100"\>

Thanks,

Neil

---

<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:** [October 6, 2011, 6:45pm UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/2 "2011-10-06T18:45:39Z")

</div>

Your index creation is wrong, the analysis part needs to come under the  
"settings" element. I created a gist that shows it:  
[gist:1268256 · GitHub](https://gist.github.com/1268256). You might not have seen a proper error  
response from the create index request because of this bug (  
[Malformed REST create index causes the index to still be created · Issue #1359 · elastic/elasticsearch · GitHub](https://github.com/elasticsearch/elasticsearch/issues/1359)).

Also, you ask why you get a result for the query you execute. Both with the  
standard analyzer and the ngram based filter one, you will get a result for  
it.

On Thu, Oct 6, 2011 at 6:59 AM, Neil [neilmatthewlott@gmail.com](mailto:neilmatthewlott@gmail.com) wrote:

> I have the following index
> 
> curl -XPUT '[http://localhost:9200/test/](http://localhost:9200/test/)' -d '{  
> "settings": {  
> "number\_of\_shards": 1,  
> "number\_of\_replicas": 0  
> },
> 
> "analysis": {  
> "analyzer": {  
> "containsText" : {  
> "tokenizer": "whitespace",  
> "filter": ["asciifolding", "lowercase", "autocomplete"]  
> }  
> },  
> "filter": {  
> "autocomplete": {"type": "edgeNGram", "min\_gram": "1",  
> "max\_gram": "100", "side": "front"}  
> }  
> },
> 
> "mappings": {  
> "program" : {  
> "properties" : {  
> "title": {"type" : "string", "store" : "yes",  
> "index" : "analyzed" , "term\_vector" : "with\_positions\_offsets",  
> "analyzer" : "containsText"}  
> }  
> }  
> }  
> }'
> 
> curl -XPUT [http://localhost:9200/test/program/1652094](http://localhost:9200/test/program/1652094) -d '{  
> "title": "James Franco"  
> }'
> 
> So my question is why does this return a result?
> 
> curl -XGET [http://localhost:9200/test/program/\_search](http://localhost:9200/test/program/_search) -d '{  
> "query" : {  
> "queryString" : {  
> "default\_field" : "title",  
> "query" : "james i",  
> "analyzer" : "containsText"  
> }  
> }  
> }'
> 
> I don't want it to since it doesn't match on the last name. What do I  
> need to change to get my expected result?  
> I would like to have my query string analyzed the same way as my  
> indexed string.
> 
> If it helps -- I was able to do this is solr as such:
> 
> ```
> <fieldType name="containsText" class="solr.TextField"
> 
> ```
> 
> positionIncrementGap="100"\>
> 
> Thanks,
> 
> Neil

---

<div class="post-metadata">

**Author:** ![Neil1](https://avatars.discourse-cdn.com/v4/letter/n/278dde/32.png) [@Neil1](https://discuss.elastic.co/u/Neil1)\
**Post date:** [October 6, 2011, 7:04pm UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/3 "2011-10-06T19:04:57Z")

</div>

I'm sorry about goofing up the analysis -- however even when the  
analyzer is correct -- verified using the mapping:

curl -XPUT '[http://localhost:9200/test/](http://localhost:9200/test/)' -d '{  
"settings": {  
"number\_of\_shards": 1,  
"number\_of\_replicas": 0,  
"analysis": {  
"analyzer": {  
"containsText" : {  
"tokenizer": "whitespace",  
"filter": ["asciifolding", "lowercase",  
"autocomplete"]  
}  
},  
"filter": {  
"autocomplete": {"type": "edgeNGram", "min\_gram":  
"1",  
"max\_gram": "100", "side": "front"}  
}  
}  
},  
"mappings": {  
"program" : {  
"properties" : {  
"title": {"type" : "string", "store" : "yes",  
"index" : "analyzed" , "term\_vector" : "with\_positions\_offsets",  
"analyzer" : "containsText"}  
}  
}  
}  
}'

curl -XGET '[http://localhost:9200/test/program/\_mapping](http://localhost:9200/test/program/_mapping)'  
{"program":{"properties":{"title":  
{"store":"yes","analyzer":"containsText","term\_vector":"with\_positions\_offsets","type":"string"}}}}

curl -XPUT [http://localhost:9200/test/program/1652094](http://localhost:9200/test/program/1652094) -d '{  
"title": "James Franco"  
}'

And I run the following query -- it returns a result.

curl -XGET [http://localhost:9200/test/program/\_search](http://localhost:9200/test/program/_search) -d '{  
"query" : {  
"queryString" : {  
"default\_field" : "title",  
"query" : "james i",  
"analyzer" : "containsText"  
}  
}  
}'

---

<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:** [October 6, 2011, 7:09pm UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/4 "2011-10-06T19:09:08Z")

</div>

Why shouldn't it return a result? Based on your analyzer definition, it will  
return a result. Use the analyze API to see what "James Franco" and "james  
i" get broken to.

On Thu, Oct 6, 2011 at 9:04 PM, Neil [neilmatthewlott@gmail.com](mailto:neilmatthewlott@gmail.com) wrote:

> I'm sorry about goofing up the analysis -- however even when the  
> analyzer is correct -- verified using the mapping:
> 
> curl -XPUT '[http://localhost:9200/test/](http://localhost:9200/test/)' -d '{  
> "settings": {  
> "number\_of\_shards": 1,  
> "number\_of\_replicas": 0,  
> "analysis": {  
> "analyzer": {  
> "containsText" : {  
> "tokenizer": "whitespace",  
> "filter": ["asciifolding", "lowercase",  
> "autocomplete"]  
> }  
> },  
> "filter": {  
> "autocomplete": {"type": "edgeNGram", "min\_gram":  
> "1",  
> "max\_gram": "100", "side": "front"}  
> }  
> }  
> },  
> "mappings": {  
> "program" : {  
> "properties" : {  
> "title": {"type" : "string", "store" : "yes",  
> "index" : "analyzed" , "term\_vector" : "with\_positions\_offsets",  
> "analyzer" : "containsText"}  
> }  
> }  
> }  
> }'
> 
> curl -XGET '[http://localhost:9200/test/program/\_mapping](http://localhost:9200/test/program/_mapping)'  
> {"program":{"properties":{"title":
> 
> {"store":"yes","analyzer":"containsText","term\_vector":"with\_positions\_offsets","type":"string"}}}}
> 
> curl -XPUT [http://localhost:9200/test/program/1652094](http://localhost:9200/test/program/1652094) -d '{  
> "title": "James Franco"  
> }'
> 
> And I run the following query -- it returns a result.
> 
> curl -XGET [http://localhost:9200/test/program/\_search](http://localhost:9200/test/program/_search) -d '{  
> "query" : {  
> "queryString" : {  
> "default\_field" : "title",  
> "query" : "james i",  
> "analyzer" : "containsText"  
> }  
> }  
> }'

---

<div class="post-metadata">

**Author:** ![Neil1](https://avatars.discourse-cdn.com/v4/letter/n/278dde/32.png) [@Neil1](https://discuss.elastic.co/u/Neil1)\
**Post date:** [October 6, 2011, 8:17pm UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/5 "2011-10-06T20:17:10Z")

</div>

Thanks I did.

What is happening is that --

"james i" was being broken up into a Boolean Query with two clauses  
where the occur is set to should:

QueryStringQueryParser:184 value of Query object  
(title:j title:ja title:jam title:jame title:james) title:c

This means that if one matched then it would return successful.

What I really want to have happen is to have a PhraseQuery which only  
happens if you surround the query string in quotes.

curl -XGET [http://localhost:9200/test/program/\_search](http://localhost:9200/test/program/_search) -d '{  
"query" : {  
"queryString" : {  
"default\_field" : "title",  
"query" : ""james i"",  
"analyzer" : "containsText"  
}  
}

---

<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:52am UTC](https://discuss.elastic.co/t/how-to-make-a-specific-edgengram-query/5524/6 "2017-07-06T03:52:40Z")

</div>


