Elastic Search 1.7 - Full Like search like SQL - elasticsearch

Im using old version of elastic search and I can't find a way to allow full like search like sql: '%%'
I have to search a non pre-known data so the "columns" are not known.
Ex.
I have this columns ad an example of row:
source,dest,message
eth0, eth1, DELIVERY 3015801: SUCCESS: DID
In the search form, a user write something like this:
+message:"delivery"
or
+message:"delivery" and +source:"eht0"
The row is returned succesfully.
Unfortunally if they write:
+message:"success"
it return no row because of ":"
I need to allow user to write somethig like:
+message:"success*"
This is the query submitted. I have timerange filter and then the query :
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"range": {
"#timestamp": {
"from": 1561615860000,
"to": 1561619519000
}
}
}
]
}
},
"query": {
"bool": {
"should": [
{
"query_string": {
"query": "+message:\"success\""
}
}
]
}
}
}
},
"sort": [
{
"#timestamp": {
"order": "desc"
}
}
]
}
Is there a way to translate my text search in something like sql
message like 'success%'
Thanks.

Is that an analyzed or a not-analyzed field? Maybe a prefix query is what you want for that.
But generally:
This version is more than dead. Please upgrade.
This is not a relational database. If you try to translate the concepts 1:1 you will not get the most out of it. Documentation or courses will help you to move into proper search and away from LIKE searches.

Related

Elasticsearch Multi match and exact matches

My knowledge of Elasticsearch is a bit limited, so what I want to do might not even be possible.
Say I have an ecommerce where I want to be able to freely search on the article names and other fields, but I also want to search on exact article codes aswell. Is this possible in the same query?
Example:
"articlecode": "v400",
"name": "Earplugs for humans"
}
{
"articlecode": "b6655",
"name": "Hammer 400"
}
So can a query be written that combines both multimatch and terms? So that If I search for '400' I get 2 results, but if I search for v400 I just get one result as it is an exact match on the "articlecode"-field.
Below is our current query, where i have an ngram on the "name" field and where I use the term-keyword on the language-field.
{
"size": 10,
"query": {
"bool": {
"must": {
"multi_match": {
"query": "v400",
"fields": [
"articlecode^10",
"name^7"
]
}
},
"filter": {
"term": {
"IdLang.keyword": "sv"
}
}
}
}
}
Have you ever thought of using query_string instead of multi_match? Then you can use wildcard in your search:
{
"size": 10,
"query": {
"bool": {
"must": {
"query_string": {
"query": "*v400",
"fields": [
"articlecode^10",
"name^7"
]
}
}
}
}
}
If you want to search with 400 anywhere in the 2 fields, you can do *400*, or only leading or trailing, depending on what you want.

Match documents in elasticsearch with AND and OR on different fields

I am new to elastic search and I am working with MySQL and MongoDB. I want to write the query which gives products which are active and it's name or brand_name or model_number or category contains a specific word.
Here is MySQL query.
SELECT * FROM products WHERE active=0 AND (name LIKE '%car%' OR brand_name LIKE '%car%' OR model_number LIKE '%car%' OR category LIKE '%car%');
I already tried with the below query in elastic search, but it's just AND operator.
"query": {
"bool": {
"must": [
{"match": {"active": "1"}},
{"regexp": {"name": "cars.*"}},
{"regexp": {"brand_data.brand_name": "cars.*"}},
{"regexp": {"model_number": "cars.*"}},
]
}
}
Can anyone help me to write this query in elasticsearch.
Short answer - for OR you can use should occurrence of boolean query.
Long answer with example:
It can be done in several ways, but I want point you to one detail. If you need to search only active=1 or active=0 results, it will be better to use filter occurrence in your query. It will give you better performance and caching.
The clause (query) must appear in matching documents. However unlike must the score of the query will be ignored. Filter clauses are executed in filter context, meaning that scoring is ignored and clauses are considered for caching.
So I can propose you this query:
{
"query": {
"bool": {
"filter": {
"term": {
"active": "1"
}
},
"should": [
{
"regexp": {
"name": "cars.*"
}
},
{
"regexp": {
"brand_data.brand_name": "cars.*"
}
},
{
"regexp": {
"model_number": "cars.*"
}
}
]
}
}
}
You are looking for a 'or' nested inside an 'and' clause. this is the correct format:
"query": {
"bool": {
"must": [
{"match": {"active": "1"}},
{"bool":{"should":[
{"regexp": {"name": "cars.*"}},
{"regexp": {"brand_data.brand_name": "cars.*"}},
{"regexp": {"model_number": "cars.*"}}]}}
]
}
}

Create API keys on ElasticSearch with limited search capabilities

I want to create API keys on elasticsearch via POST _security/api_key API, I am able to create these but I want to limit search capability for the generated key which I am unable to do.
Essentially, what I want to achieve is let's say that all my records have a field like "username":"username1" or another one like "username":"username2" i.e. all the records will have a valid value for username field
Now what I want is to be able to create a key where I specify something like "username":"username2" which then gets appended to every search query made using that key as an AND case like if this key searches (/index_name/_search) for
{
"query": {
"match": {
"key_zz":"value_aa"
}
}
}
this query would actually be an AND of both of the below (i.e. if a record with this combination exists "key_zz":"value_aa" but the value for username is not username2, the API would not return that object)
{
"query": {
"match": {
"key_zz":"value_aa"
}
}
}
AND
{
"query": {
"must": {
"match" : {
"username":"username2"
}
}
}
}
I have tried creating the key with all of the following combinations:
"name": "key-name",
"role_descriptors": {
"role_name": {
"indices": [
{
"names": [
"index_name"
],
"privileges": [
"read"
],
"query": {
"match": {
"username": "value_custom"
}
}
}
]
}
}
}
In the query field, I have tried all the following combinations:
"query": {
"and": {
"username": "value_custom"
}
}
"query": {
"bool": {
"must": {
"match": {
"username": "value_custom"
}
}
}
}
"query": {
"bool": {
"must": {
"bool": {
"must": {
"match": {
"username": "value_custom"
}
}
}
}
}
}
But none of the above worked. Also, earlier the mapping type of username field was text but I then updated it to be keyword
In a nutshell, what I am trying to achieve is some kind of document level security. I know ElasticSearch has some kind of Document Level Security (https://www.elastic.co/guide/en/elastic-stack-overview/current/document-level-security.html) but in our architecture, we want to achieve this using API keys with restricted search capabilities. We are currently using Algolia and we were achieving this using the exact implementation I described above. ElasticSearch documentation has references for how to limit a role but not how to limit API keys. Need help to achieve this.
Also, I am using ElasticSearch v7
Some reference links :
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-create-api-key.html
https://www.elastic.co/guide/en/elasticsearch/reference/current/security-api-put-role.html

Elastic Search Query (a like x and y) or (b like x and y)

Some background info: In the bellow example user searched for "HTML CSS". I split each word from the search string and created the SQL query seen bellow.
Now I am trying to make an elastic search query that has the same logic as the following SQL query:
SELECT
title, description
FROM `classes`
WHERE
(`title` LIKE '%html%' AND `title` LIKE '%css%') OR
(description LIKE '%html%' AND description LIKE '%css%')
Currently, half way there but can't seem to get it right yet.
{
"query": {
"bool": {
"must": [
{
"term": {
"title": "html"
}
},
{
"term": {
"title": "css"
}
}
]
}
},
"_source": [
"title"
],
"size": 30
}
Now I need to find how to add follow logic
OR (description LIKE '%html%' AND description LIKE '%css%')
One important point is that I need to only fetch documents that have both words in either title or disruption. I don't want to fetch documents that have only 1 word.
I will update questions as I find more info.
Update: The chosen answer also provides a way to boost scoring based on the field.
Can you try following query. You can use should for making or operation
{
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"match": { // Go for term if your field is analyzed
"title": {
"query": "html css",
"operator": "and",
"boost" : 2
}
}
}
]
}
},
{
"bool": {
"must": [
{
"match": {
"description": {
"query": "html css",
"operator": "and"
}
}
}
]
}
}
],
"minimum_number_should_match": 1
}
},
"_source": [
"title",
"description"
]
}
Hope this helps!!
I feel most appropriate query to be used in this case is multi_match.
multi_match query is convenient way of running the same query on
multiple fields.
So your query can be written as:
GET /_search
{
"_source": ["title", "description"],
"query": {
"multi_match": {
"query": "html css",
"fields": ["title^2", "description"],
"operator":"and"
}
}
}
_source filters the dataset so that only fields mentioned in array
will be displayed in results.
^2 denotes boosting title field with the number 2
operator:and makes sure that all terms in query must be matched
in either fields
From the elasticsearch 5.2 doc:
One option is to use the nested datatype instead of the object datatype.
More details here: https://www.elastic.co/guide/en/elasticsearch/reference/5.2/nested.html
Hope this helps

elastic search where clause with constant rank?How to do this?

I'm new to elastic search. How to generate elastic search equivalent query for
select * from response where pnrno='sampleid'
I know we have to use 'filter' option in elastic search.but we do not need any ranking. (ranking can be constant) so how can I generate query for achieve this
you are correct , you can use filtered query with query clause empty and filters.Filtering a set of documents is to filter the sets upon which query acts to furthur filter/match and calculate relevance.Filters are like bool either match or reject(1/0).
{
"query": {
"filtered": {
"filter": {
"bool": {
"must": [{
"term": {
"FIELD": "VALUE"
}
}]
}
}
}
}
}
The usual way of achieving this is by using the constant_score query with an embedded term filter, like this:
{
"query": {
"constant_score": {
"filter": {
"term": {
"pnrno": "sampleid"
}
}
}
}
}

Resources