What's the reason for specifying only the 'field' option for the Term & Phrase suggesters in elasticsearch - elasticsearch

When using the suggester API, we are forced to specify the field option :
"suggest" : {
"text" : "val",
"sug_name" : {
"term" : {
"field" : "field_name"
}
}
}
Is this field supposed to be a valid field name of some type ?
If so, fields can exist only in the context of types AFAIK.
Why isn't possible to also specify (at least optionally) the type the field belongs to ?

Is your question if "field" has to be a valid field?
YES it does if you want it to find anything, you are welcome to search for fields that dont exist, although that seems an odd thing to do.
Your second question, the answer, I believe, is NO, you can not specify a _type using the _suggest api, you can use a suggest block with the _search api as shown here
curl -s -XPOST 'localhost:9200/_search' -d '{
"query" : {
...
},
"suggest" : {
...
}
}'

Related

How to run Elasticsearch completion suggester query on limited set of documents

I'm using a completion suggester in Elasticsearch on a single field. The type contains documents of several users. Is there a way to limit the returned suggestions to documents that match a specific query?
I'm currently using this query:
{
"name" : {
"text" : "Peter",
"completion" : {
"field" : "name_suggest"
}
}
}
Is there a way to combine this query with a different one, e.g.
{
"query":{
"term" : {
"user_id" : "590c5bd2819c3e225c990b48"
}
}
}
Have a look at the context suggester, which is just a specialized completion suggester with filtering capabilities - however this is still not a regular query filter, just keep that in mind.
You can specify both the query and the suggester in your query, like this:
{
"query":{
"term" : {
"user_id" : "590c5bd2819c3e225c990b48"
}
},
"suggest": {
"name" : {
"text" : "Peter",
"completion" : {
"field" : "name_suggest"
}
}
}
}
I have a similar use case, and I've posted my question on elastic search forum, see here
From what I've read so far, I don't think with completion suggester you can limit documents. They essentially create a finite state transducer (prefix tree) at index time, this makes it fast but you lose the flexibility of filtering on additional fields. I don't think context suggester would work in your case (let me know if i am wrong), because the cardinality of user_id is very high.
I think edge-ngrams partial matching is more flexible and might actually work in your use case.
Let me know what you end up implementing.

How to get elasticsearch suggestions working on multiple fields from multiple types?

I have a requirement to have a search box globally on the website that user can type anything in, a bit like google. As the user is typing along, he should get suggestions. I have multiple types in an Index, I am using Completion suggester to get suggestions from one field like below:
GET /index/_suggest/
{
"person-suggest" : {
"text" : "m",
"completion" : {
"field" : "nameSuggest"
}
}
}
The requirement is such that when they type a person name which is stored in person type or type in a company name which is stored in company type...both suggestions should appear. Also, within the same type, it should be able to suggest based on multiple fields not just one like what I've got. And finally once the user selects a suggestion, do a search and show facets which are based on multiple types.
For multi-type suggestions on multiple fields, use-
curl -XPOST 'localhost:9200/indexName/type1,type2/_suggest' -d '{
"my-suggestion-1" : {
"text" : "some text",
"term" : {
"field" : "field1"
}
},
"my-suggestion-2" : {
"text" : "some text",
"term" : {
"field" : "field2"
}
}
}'

how to copy ElasticSearch field to another field

I have 100GB ES index now. Right now I need to change one field to multi-fields, such as: username to username.username and username.raw (not_analyzed). I know it will apply to the incoming data. But how can I make this change affect on the old data? Should I using index scroll to copy the whole index to a new one, Or there is a better solution to just copy one filed please.
There's a way to achieve this without reindexing all your data by using the update by query plugin.
Basically, after installing the plugin, you can run the following query and all your documents will get the multi-field re-populated.
curl -XPOST 'localhost:9200/your_index/_update_by_query' -d '{
"query" : {
"match_all" : {}
},
"script" : "ctx._source.username = ctx._source.username;"
}'
It might take a while to run on 100GB docs, but after this runs, the username.raw field will be populated.
Note: for this plugin to work, one needs to have scripting enabled.
POST index/type/_update_by_query
{
"query" : {
"match_all" : {}
},
"script" :{
"inline" : "ctx._source.username = ctx._source.username;",
"lang" : "painless"
}
}
This worked for me on es 5.6, above one did not!

Elasticsearch: how to query a long field for exact match

My document has the following mapping property:
"sid" : {"type" : "long", "store": "yes", "index": "no"},
This property has only one value for each record. I would like to query this property. I tried the following queries:
{
"query" : {
"term" : {
"sid" : 10
}
}
}
{
"query" : {
"match" : {
"sid" : 10
}
}
}
However, I got no results. I do have a document with sid being euqal to 10. Anything I did is wrong? I would like to query this property for exact match.
Thanks and regards.
Quote from the documentation:
index: Set to analyzed for the field to be indexed and searchable after being
broken down into token using an analyzer. not_analyzed means that its
still searchable, but does not go through any analysis process or
broken down into tokens. no means that it won’t be searchable at all
(as an individual field; it may still be included in _all). Setting to
no disables include_in_all. Defaults to analyzed.
So, by setting index to no you cannot search by that field individually. So, you either need to remove no from index and choose something else or you can use "include_in_all":"yes" and use a different type of query:
"query": {
"match": {
"_all": 10
}
}

Special Character "- " in the Elastic Search acting

"-" is acting like a or operator for e.g. I am searching "t-link", then it showing the result containing "t-link" as well as "t", why it is giving two terms, but i interested in the "t-link", why it is happening so? How can i recover from it?
Elasticsearch is using by default the standard analyzer for strings.
Basically, your string is tokenized in two tokens, lowercased:
t
link
If you need to know what does elasticsearch with your fields, use the _analyze API.
$ curl -XGET 'localhost:9200/_analyze?analyzer=standard' -d 't-link'
$ curl -XGET 'localhost:9200/_analyze?analyzer=simple' -d 't-link'
If you don't want that, make sure you put the right mapping for that field and use either a simple analyzer or a keyword analyzer or no analyzer at all depending on your requirements. See also String core type.
$ curl -XPUT 'http://localhost:9200/twitter/tweet/_mapping' -d '
{
"tweet" : {
"properties" : {
"message" : {"type" : "string", "analyzer" : "simple"},
"other" : {"type" : "string", "index" : "not_analyzed"}
}
}
}
'
Using this form message field will be analyzed with simple analyzer and other field won't be analyzed at all.

Resources