Elasticsearch OR query - elasticsearch

Can anyone tell me how do I write the below Mysql query in elastisearch
Select * from `table` WHERE `Name`='A' OR `Name`='B' order by `rank` DESC
I have tried multiple solutions the internet like
{
"sort":{"rank":{"order":"desc"}},
"query": {
"query_string" : {
"fields" : ["Name"],
"query" : "A OR B"
}
}
and also tried the below code
{
"sort":{"rank":{"order":"desc"}},
"query" : {
"bool": {
"should": [
{
"match_phrase" : {
"Name" : "A"
}
},
{
"match_phrase": {
"Name": "B"
}
}
]
}
}
}

You could do it with Bool-Filter and Order on all Documents:
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"should": [
{
"term": {
"Name": "A"
}
},{
"term": {
"Name": "B"
}
}
]
}
},"sort": [
{
"rank": {
"order": "desc"
}
}
]
}
Or have a subset with Range Query:
"query": {
"range": {
"JoinDate": {
"lte": 1431051540
}
}
}

This is my current mappings are
{
"class": {
"mappings": {
"students": {
"properties": {
"Name": {
"type": "string"
},
"rank": {
"type": "string"
},
"Description": {
"type": "string"
},
"Image": {
"type": "string"
},
"JoinDate": {
"type": "date",
"format": "dateOptionalTime"
}
}
}
}
}
}

Try Terms filter. Below is equivalent of SQL query you wrote.
curl -XGET 'http://localhost:9200/_search?pretty' -d '{
"filter": {
"terms": {
"Name": ["A", "B"]
}
},
"sort": {
"rank": {
"order": "desc"
}
}
}'

Related

Elasticsearch has_child returning no results

I'm trying to get all child of a parent document but not getting any result with has_child query,
{
"index": "index_x",
"include_type_name": true,
"body": {
"mappings": {
"agents": {
"properties": {
"id": {
"type": "keyword"
},
"listings": {
"type": "join",
"eager_global_ordinals": true,
"relations": {
"agent": "listing"
}
},
"name": {
"type": "object"
}
}
}
}
}
}
here's my query
{
"query": {
"bool": {
"must": [
{
"term": {
"_id": <id>
}
},
{
"has_child": {
"type": "listing",
"query": {
"match_all": {}
},
"inner_hits": {}
}
}
]
}
}
}
however, when I run this query I'm getting child results just fine
{
"query": {
"bool": {
"must": [
{
"parent_id": {
"type":"listing",
"id": <id>
}
}
]
}
}
}
Same with has_parent query, not getting any results.
I'm using Elasticsearch 7.7
Sounds like you want to use the has_parent query. Here is minimal example of how it can work on ESv7.7:
PUT /so
{
"mappings": {
"properties" : {
"my-join-field" : {
"type" : "join",
"relations": {
"parent": "child"
}
},
"tag" : {
"type" : "keyword"
}
}
}
}
POST /so/_doc/1
{
"my-join-field": "parent",
"tag": "Adult"
}
POST /so/_doc/2?routing=1
{
"my-join-field": {
"name": "child",
"parent": "1"
},
"tag": "Youth"
}
POST /so/_doc/3?routing=1
{
"my-join-field": {
"name": "child",
"parent": "1"
},
"tag": "Youth2"
}
GET /so/_search
{
"query": {
"has_parent": {
"parent_type": "parent",
"query": {
"match": {
"tag": "Adult"
}
}
}
}
}

OR query in nested objects ElasticSearch

I use ElasticSearch version 1.7.5 and I am trying to fetch all documents where missing some fields.
My mapping:
...
"participant": {
"properties": {
"id": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"name": {
"type": "string"
}
},
"coordinator": {
"properties": {
"id": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"name": {
"type": "string"
}
}
...
I want to query all documents that don't have assigned coordinator.id or participant.id yet.
My query looks like:
"query": {
"nested": {
"path": "coordinator, participant",
"query": {
"constant_score": {
"filter": {
"or": [
{
"missing": {
"field": "coordinator.id"
}
},
{
"missing": {
"field": "participant.id"
}
},
]
}
}
}
}
}
You do OR queries via the bool query:
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-bool-filter.html
So this query would work:
{
"query": {
"bool": {
"should": [
{
"constant_score": {
"filter": {
"missing": {
"field": "participant.id"
}
}
}
},
{
"constant_score": {
"filter": {
"missing": {
"field": "coordinator.id"
}
}
}
}
]
}
}
}
I noticed that you were using a nested query though the mapping does not state that coordinator and participant are nested field types so that will not work:
https://www.elastic.co/guide/en/elasticsearch/reference/1.7/mapping-nested-type.html
Setting something as a nested type is only useful when you need to group search terms together so I don't think it is necessary for you.

Elasticsearch - return aggregation to match a specific value?

Using Elasticsearch 2, is it possible to return an aggregation where a document category matches a specific field value? For example, I want to get all the categories where categories.type = "application".
My mapping looks like this:
"mappings": {
"products": {
"_all": {
"enabled": true
},
"properties": {
"title": {
"type": "string"
},
"categories": {
"type":"nested",
"properties": {
"type": {
"type": "string",
"index": "not_analyzed"
},
"name": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}
}
My query looks like this, which returns all category types, but I want to filter just the ones where categories.type = "application".
{
"query":{
"multi_match": {
"query": "Sound",
"fields": [
"title"
]
}
},
"aggs":{
"Applications": {
"nested": {
"path": "categories"
},
"aggs": {
"meta": {
"terms": {
"field": "categories.type"
},
"aggs": {
"name": {
"terms": {
"field": "categories.name"
}
}
}
}
}
}
}
}
You can use aggregation filter if I understand correctly:
{
size : 50,
"query":{
"multi_match": {
"query": "Sound",
"fields": [
"title"
]
}
},
"aggs":{
"Applications": {
"nested": {
"path": "categories"
},
"aggs": {
"meta": {
"filter" : {
"term" : {
"categories.type" : "application"
}
},
"aggs": {
"name": {
"terms": {
"field": "categories.name"
}
}
}
}
}
}
}
}
Hope that helpes.
You just need to replace "include": ".*" to "include": "application"
{
"query":{
"multi_match": {
"query": "Sound",
"fields": [
"title"
]
}
},
"aggs":{
"Applications": {
"nested": {
"path": "categories"
},
"aggs": {
"meta": {
"terms": {
"field": "categories.type"
, "include": "application"
},
"aggs": {
"name": {
"terms": {
"field": "categories.name"
}
}
}
}
}
}
}
}

Elasticsearch, how to use filter gte on specific structure

I'm trying to learn Elasticsearch, and therefore I'm trying to find a good data structure, that will fit my needs for querying.
My data structure actually looks like this :
{
"questions": [
{
"id": "n1-pain-score",
"name": "Pain score",
"answer": {
"value": 3,
"label": "Small pain"
}
},
{
"id": "n2-temperature",
"name": "Temperature",
"answer": {
"value": 37.5,
"label": "37.5°C"
}
}
]
}
For a given patient, there are multiple questions and answers.
Is there a way to take advantage of Elasticsearch filtered queries and say :
I want to see the patients that have a pain score over 6 ?
Note that I'm only testing and I still can modify the data structure to get what I want :).
It is possible to do with a filtered query. A plain query will also do:
GET {index}/{type}/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "Pain score"
}
},
{
"range": {
"answer.value": {
"gt":6
}
}
}
]
}
}
}
I suggest the following mapping and queries. Most important part - questions needs to be of type nested so that the id matching should of the same element of questions. Meaning the id with value n1-pain-score must belong to the same element that also contains answer.value: 3.
DELETE test
PUT /test
{
"mappings": {
"test": {
"properties": {
"questions": {
"type": "nested",
"properties": {
"answer": {
"properties": {
"label": {
"type": "string"
},
"value": {
"type": "long"
}
}
},
"id": {
"type": "string",
"fields": {
"notAnalyzed": {
"type": "string",
"index": "not_analyzed"
}
}
},
"name": {
"type": "string"
}
}
}
}
}
}
}
POST /test/test/1
{
"questions": [
{
"id": "n1-pain-score",
"name": "Pain score",
"answer": {
"value": 3,
"label": "Small pain"
}
},
{
"id": "n2-temperature",
"name": "Temperature",
"answer": {
"value": 37.5,
"label": "37.5°C"
}
}
]
}
GET /test/_search
{
"query": {
"nested": {
"path": "questions",
"query": {
"bool": {
"must": [
{
"term": {
"questions.id.notAnalyzed": {
"value": "n1-pain-score"
}
}
},
{
"range": {
"questions.answer.value": {
"gte": 3
}
}
}
]
}
}
}
}
}
GET /test/_search
{
"query": {
"nested": {
"path": "questions",
"query": {
"bool": {
"must": [
{
"term": {
"questions.id.notAnalyzed": {
"value": "n2-temperature"
}
}
},
{
"range": {
"questions.answer.value": {
"gte": 38
}
}
}
]
}
}
}
}
}

An Elasticsearch filter to determine the absence of a value

I have a document that has students and grades for each student. It looks something like this:
"name": "bill",
"year": 2015,
"grades": [
{"subject": "math", grade: "A"},
{"subject": "english", grade: "B"}
], ...
I'm looking for query filter(s) that can give me:
a list of students who have studied 'math', and
a list of students who have not studied 'math'.
I'm thinking that an exists filter should do it, but I'm struggling to get my head around it.
It's a stylised example but the mappings are something like this:
"mappings": {
"student": {
"properties": {
"name": {
"type": "string"
},
"grades": {
"type": "nested",
"properties": {
"subject": {
"type": "string"
},
"grade": {
"type": "string"
}
}
}
}
}
}
You need to change a bit your mapping and, depending on the your needs, I'd suggest aggregations.
First, your nested object needs to be "include_in_parent": true so that you can easily do the not studied 'math' part:
PUT /grades
{
"mappings": {
"student": {
"properties": {
"name": {
"type": "string"
},
"grades": {
"type": "nested",
"include_in_parent": true,
"properties": {
"subject": {
"type": "string"
},
"grade": {
"type": "string"
}
}
}
}
}
}
}
And the full query, using aggregations:
GET /grades/student/_search?search_type=count
{
"aggs": {
"studying_math": {
"filter": {
"nested": {
"path": "grades",
"query": {
"filtered": {
"filter": {
"bool": {
"must": [
{
"term": {
"grades.subject": "math"
}
}
]
}
}
}
}
}
},
"aggs": {
"top_10": {
"top_hits": {
"size": 10
}
}
}
},
"not_studying_math": {
"filter": {
"bool": {
"must_not": [
{
"term": {
"grades.subject": "math"
}
}
]
}
},
"aggs": {
"top_10": {
"top_hits": {
"size": 10
}
}
}
}
}
}
A term filter should do just fine. For the inverse query, just negate it with a not filter:
"query":
{
"filtered" : {
"query": {
"match_all": {}
},
"filter" : {
"term": {
"grades.subject": "math"
}
}
}
}
And for the ones who did not study math:
"query":
{
"filtered" : {
"query": {
"match_all": {}
},
"filter" : {
"not": {
"filter": {
"term": {
"grades.subject": "math"
}
}
}
}
}
}

Resources