How can I find entries in elastic where a specific value is present in array? - elasticsearch

Ok, this is the schema:
id
generated{
status{
myStatuses[]
}
}
So having now these entries:
id=1
generated.status.myStatuses=['busy', 'free']
id=2
generated.status.myStatuses=['busy']
id=3
generated.status.myStatuses=['free']
I want to match all the documents where "generated.status.myStatuses" contains the word "free".
In the example above I would find id=1 and id=3.

There's no dedicated array datatype in ES so you can treat your keyword arrays as keywords. This means either
GET generated/_search
{
"query": {
"match": {
"generated.status.myStatuses": "free"
}
}
}
or, for exact matches,
GET generated/_search
{
"query": {
"term": {
"generated.status.myStatuses.keyword": "free"
}
}
}

{
"query":{
"match":{
"generated.status.myStatuses":"free"
}
}
}
You need to use match or term queries based on your data mapping.

Related

ElasticSearch query text

My index data is
{
"full_name":"Edwin Powell Hubble",
"job": "IT"
}
{
"full_name":"John Edwin",
"job": "Accountant"
}
{
"first_name":"Eric Petterson",
"job": "Accountant"
}
I am not sure if anyone could help me to build a query to get data that have full_name as Edwin. It tried with term query seem not really work.
Since full_name can be of any length and should be analyzed when indexed, I believe you have mapped the attribute as of type text.
For the same reason I also believe you will have requirements to return results as 'Edwin Powell Hubble' and 'John Edwin' when searched with 'Edwin' and return 'Edwin Powell Hubble' when search with 'Edwin Pow'
match_phrase_prefix should help you with these use cases.
GET /_search
{
"query": {
"match_phrase_prefix": {
"full_name": "Edwin"
}
}
}
You can use the match query to get data that have full_name as Edwin
{
"query": {
"match": {
"full_name": "edwin"
}
}
}
Term query works on exact text match, so you will not get any document for Edwin since there is no data in your sample index data that have a match for full_name as Edwin

Elsticsearch : Contains query

I have a column in my mapping that holds an array of strings
col1
["asd","fgh","wer"]
["qwer","cvbvbn","popop"]
["cvbml","fhjhfrjk","fsdfd"]
["asd","trth","fdf"]
The column col is not analyzed in the index and i do not want to change the mapping.
"col1":
{
"type":"string",
"index":"not_analyzed"
}
Now, i want to retrieve all records where the string asd appears. so in this case, i want the first and fourth records. I tried using the query
query: {
wildcard:{
"col1":"asd"
}
}
with
POST localhost:9200/indexName/test/_search
but that gives me empty results? Which query should i use in this case?
Edit
So i was able to solve the above problem. Here is a follow up. Consider that this was my data
col1
["asd fd","fgh bn","wer kl"]
["qwer","cvbvbn","popop"]
["cvbml","fhjhfrjk wewe","fsdfd rtr"]
["asd","trth","fdf"]
so now, the array contains some strings that have multiple words. Now, i still want to return the first and fourth record. If i go with the solution that i posted, i only get the fourth one. How can i apply the contains logic to each element of the array in col1?
Note
A partial solution is
{ "query": { "match_phrase_prefix": { "col1": "asd" } } }
so again, for the data
col1
["asd fd","fgh bn","wer kl"]
["qwer","cvbvbn","popop"]
["cvbml","fhjhfrjk wewe","fsdfd rtr"]
["asd","trth","fdf"]
it returns the first and fourth records. However, if i have
col1
["fd asd","fgh bn","wer kl"]
["qwer","cvbvbn","popop"]
["cvbml","fhjhfrjk wewe","fsdfd rtr"]
["asd","trth","fdf"]
then, once again it only returns the fourth one, which is understandable as now, asd is no longer a prefix for that value in the first record.
Is there a way to to a contains type match instead of just prefix match?
You can use a simple term query and it should work
POST localhost:9200/indexName/test/_search
{
"query": {
"terms": { "col1" : "asd" }
}
}
so, here is the proper query
{
fields : ["col1","col2"],
query: {
filtered: {
query: {
match_all: {}
},
filter: {
terms: {
col1: ["asd"]
}
}
}
}
}
Final Answer
query: {
wildcard:{
col1:{
value:"*asd*"
}
}
}
:)

Scope Elasticsearch Results to Specific Ids

I have a question about the Elasticsearch DSL.
I would like to do a full text search, but scope the searchable records to a specific array of database ids.
In SQL world, it would be the functional equivalent of WHERE id IN(1, 2, 3, 4).
I've been researching, but I find the Elasticsearch query DSL documentation a little cryptic and devoid of useful examples. Can anyone point me in the right direction?
Here is an example query which might work for you. This assumes that the _all field is enabled on your index (which is the default). It will do a full text search across all the fields in your index. Additionally, with the added ids filter, the query will exclude any document whose id is not in the given array.
{
"bool": {
"must": {
"match": {
"_all": "your search text"
}
},
"filter": {
"ids": {
"values": ["1","2","3","4"]
}
}
}
}
Hope this helps!
As discussed by Ali Beyad, ids field in the query can do that for you. Just to complement his answer, I am giving an working example. In case anyone in the future needs it.
GET index_name/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"field": "your query"
}
},
{
"ids" : {
"values" : ["0aRM6ngBFlDmSSLpu_J4", "0qRM6ngBFlDmSSLpu_J4"]
}
}
]
}
}
}
You can create a bool query that contains an Ids query in a MUST clause:
https://www.elastic.co/guide/en/elasticsearch/reference/2.0/query-dsl-ids-query.html
By using a MUST clause in a bool query, your search will be further limited by the Ids you specify. I'm assuming here by Ids you mean the _id value for your documents.
According to es doc, you can
Returns documents based on their IDs.
GET /_search
{
"query": {
"ids" : {
"values" : ["1", "4", "100"]
}
}
}
With elasticaBundle symfony 5.2
$query = new Query();
$IdsQuery = new Query\Ids();
$IdsQuery->setIds($id);
$query->setQuery($IdsQuery);
$this->finder->find($query, $limit);
You have two options.
The ids query:
GET index/_search
{
"query": {
"ids": {
"values": ["1, 2, 3"]
}
}
}
or
The terms query:
GET index/_search
{
"query": {
"terms": {
"yourNonPrimaryIdField": ["1", "2","3"]
}
}
}
The ids query targets the document's internal _id field (= the primary ID). But it often happens that documents contain secondary (and more) IDs which you'd target thru the terms query.
Note that if your secondary IDs contain uppercase chars and you don't set their field's mapping to keyword, they'll be normalized (and lowercased) and the terms query will appear broken because it only works with exact matches. More on this here: Only getting results when elasticsearch is case sensitive

How do I search within an list of strings in Elastic Search?

My data has a field localities which is an array of strings.
"localities": [
"Mayur Vihar Phase 1",
"Paschim Vihar",
"Rohini",
"",
"Laxmi Nagar",
"Vasant Vihar",
"Dwarka",
"Karol Bagh",
"Inderlok" ]
What query should I write to filter the documents by a specific locality such as "Rohini"?
A simple match query will be enough (if you don't know the mapping of your localities field).
POST <your index>/_search
{
"query": {
"match": {
"localities": "Rohini"
}
}
}
If the localities field is set as a string type and index as not_analyzed, the best way to query this is to use a term filter, wrapped in a filtered query (you can't use directly filters) :
POST <your index>/_search
{
"query": {
"filtered": {
"filter": {
"term": {
"localities": "Rohini"
}
}
}
}
}
If you doesn't need the score, the second solution is the way to go as filters doesn't compute score, are faster and cached.
Check the documentation for information about analysis which is a very important subject in ElasticSearch, heavily influencing the way you query.
POST /_search
{
"query": {
"match": {
"localities": "Rohini"
}
}
}
Or you can simply query:
GET /_search?q=localities:Rohini

elasticsearch - confused on how to searching items that a field contains string

This query is returning fine only one item "steve_jobs".
{
"query": {
"constant_score": {
"filter": {
"term": {
"name":"steve_jobs"
}
}
}
}
}
So, now I want to get all people with name prefix steve_. So I try this:
{
"query": {
"constant_score": {
"filter": {
"term": {
"name": "steve_"
}
}
}
}
}
This is returning nothing. Why?
I'm confused about when to use term query / term filter / terms filter / querystring query.
What you need is Prefix Query.
If you are indexing your document like so:
POST /testing_nested_query/class/
{
"name": "my name is steve_jobs"
}
And you are using the default analyzer, then the problem is that the term steve_jobs will be indexed as one term. So your Term Query will never be able to find any docs matching the term steve as there is no term like in the index. Prefix Query helps you solve your problem by searching for a prefix in all the indexed terms.
You can solve the same problem by making your custom analyzers (read this and this) so that steve_jobs is stored as steve and jobs.

Resources