fuzzy searching with query_string Elasticsearch - elasticsearch

i have a record saved in Elasticsearch which contains a string exactly equals to Clash of clans
now i want to search this string with Elasticsearch and i using this
{
"query_string" : {
"query" : "clash"
}
}
its working perfectly but now if i write
"query" : "class"
it dont give me back any record so i realize i should use Fuzzy searching so i come to know that i can use fuzziness parameter with query_string so i did
{
"query_string" : {
"query" : "clas"
"fuzziness":1
}
}
but still elasticsearch is not returning anything!
kindly help and i cant use Fuzzy query i just can use query_string.
Thanks

You need to use the ~ operator to have fuzzy searching in query_string:
{
"query": {
"query_string": {
"query": "class~"
}
}
}

Related

Single bool must queries in Elasticsearch

Does wrapping single Elasticsearch queries in bool must queries change search results, or are the following two queries identical (both in terms of how elasticsearch processes them and what the outcome is)?
single query_string query (no bool query as wrapper):
POST _search
{
"query": {
"query_string" : { "query" : "My query string" }
}}
bool query that wrapps a single query_string query:
POST _search
{
"query": {
"bool" : {
"must" : {
"query_string" : { "query" : "My query string" }
}}}}
Both are exactly semantically the same and will produce the same results.
It's worth noting, though, that a bool query only makes sense if there are more than one clause, otherwise it's useless to specify it.

Combining results of two queries

I'm using Kibana v6.1.1 and trying to get within one GET request two different queries in order to use the "must" or "should" terms more than once.
When I run this query under "Dev Tools" in the Kibana, it works.
When I want to apply this "double query" (without the GET line of course) under "Discover"->"Add a filter"->"Edit filter"->"Edit Query DSL", it doesn't accept the syntax {} in order to create an 'OR' between the queries.
It is necessary that these two "must" terms will be separated but stay in the same filter.
GET _my_index/_search
{
"query" : {
"bool" : {
"must" : [{
...
}]
}
}
}
{}
{
"query" : {
"bool" : {
"must" : [{
...
}]
}
}
}
P.S.
Using the simple_query_string doesn't seem to solve the problem and so far, I couldn't find the way to combine these two queries.
I'm not sure what you actually want to achieve. Use the following if at least one of the shoulds has to match (there is an implicit minimum_should_match if there are no other conditions, but you can also set an explicit value for that):
{
"query" : {
"bool" : {
"should" : [
{
...
},
{
...
}
]
}
}
}
If you want to run independent queries, use a multi search.

How to convert filtered query with Multi_Match to filtered query with Common Terms

I am using ES 2.0. I have the following filtered query with multi_match:
{
"filtered" : {
"query": {
"multi_match" : {
"query" : "sleep",
"fields" : ["title.*^10","introduction.*"],
"cutoff_frequency" : 0.001,
"operator" : "or",
"analyzer" : "standard"
}
},
"filter" : {
...
}
}
Because of stop words issue, I would like to replace the Multi_Match with Common Terms explained here: https://www.elastic.co/blog/stop-stopping-stop-words-a-look-at-common-terms-query
How can I just replace the above multi_match with Common Terms? I cannot figure out how to handle the search on multiple fields based on Common Terms.
Thanks!
When specifying the cutoff_frequency in your multi_match query, you're already using common terms, as mentioned in the blog article you linked to:
"Common Terms has also been incorporated into the Match query and can
be enabled by setting cutoff_frequency to a value like 0.001"
The documentation for match and multi_match on cutoff_frequency also mention this fact.

escaping forward slashes in elasticsearch

I am doing a general search against elasticsearch (1.7) and all is well except my account numbers have forward slashes in them. The account number field is not the id field and is "not_analyzed".
If I do a search on an account number e.g. AC/1234/A01 then I get thousands of results, presumably because it is doing a regex search (?).
{
"query" : { "query_string" : {"query" : "AC/1234/A01"} }
}
I can get the result I want by doing an exact match search
{
"query" : { "query_string" : {"query" : "\"AC/1234/A01\""} }
}
This actually gives me the result I want and probably will fit the bill as a backup option (surrounding all 'single word' searches with quotes). However I'm thinking if they do a multiple word search including the account number I will be back to thousands of results and although I can't see the value of that search I would like to avoid it happening.
Essentially I have a java app querying elastic search and I would like to escape all forward slashes entered in the GUI.
My Googling has told me that
{
"query" : { "query_string" : {"query" : "AC\\/1234\\/A01"} }
}
ought to do this but it makes no difference, the query works but I still get thousands of results.
Could anyone point me in the right direction ?
You should get what you want without escaping anything simply by specifying a keyword analyzer for the query string, like this:
{
"query" : {
"query_string" : {
"query" : "AC\\/1234\\/A01",
"analyzer": "keyword" <---- add this line
}
}
}
If you don't do this, the standard analyzer is used (and will tokenize your query string) whatever the type of your field is or whether it is not_analyzed or not.
Use this query as example:
{
"query": {
"query_string": {
"fields": [
"account_number.keyword"
],
"query": "AC\\/1234\\/A01",
"analyzer": "keyword"
}
}
}
I use query_string because I want to give my users the possibility to do complex queries with OR and AND. Having the search break when a slash is used (e.g. when searching for an URL) is not helpful.
I worked around that issue by adding quotes when a slash is in the search string but no quotes:
if (strpos($query, '/') !== false && strpos($query, '"') === false) {
$query = '"' . $query . '"';
}

Elastic Search boost query corresponding to first search term

I am using PyElasticsearch (elasticsearch python client library). I am searching strings like Arvind Kejriwal India Today Economic Times and that gives me reasonable results. I was hoping I could increase weight of the first words more in the search query. How can I do that?
res = es.search(index="article-index", fields="url", body={
"query": {
"query_string": {
"query": "keywordstr",
"fields": [
"text",
"title",
"tags",
"domain"
]
}
}
})
I am using the above command to search right now.
split given query into multiple terms. In your example it will be Arvind, Kejriwal... Now form query string queries(or field query or any other which fits into the need) for each of the given terms. A query string query will look like this
http://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/query-dsl-query-string-query.html
{
"query_string" : {
"default_field" : "content",
"query" : "<one of the given term>",
"boost": <any number>
}
}
Now you have got multiple queries like above with different boost values(depending upon which have higher weight). Combine all of those queries into one query using BOOL query. http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
If you want all of the terms to be present in the result, query will be like this.
{
"bool" : {
"must" : [q1, q2, q3 ...]
}
}
you can use different options of bool query. for example you want any of 3 terms to present in result then query will be like
{
"bool" : {
"should" : [q1, q2,q3 ...]
},
"minimum_should_match" : 3,
}
theoretically:
split into terms using api
query against terms with different boosting
Lucene Query Syntax does the trick. Thanks
http://lucene.apache.org/core/2_9_4/queryparsersyntax.html#Boosting%20a%20Term

Resources