Elasticsearch inner-hits on child type not in the query - elasticsearch

Struggling with inner-hits on elasticsearch. Would appreciate any help.
I have two child types: childA and childB.
I am querying parents of childA like this
"query":{
"bool": {
"should": {
"has_child": {
"type": "ChildA",
"query": {
"match": {
"name": {
"query": "a"
}
}
}
}
}
}
}
My problem is how to include in the results all child docs of type childB as well without affecting results from the above query.
I was thinking to use inner-hits on a has_child query(type childB) for that but my query doesn't depend on childB type.
Anyone has an idea?
Thanks in advance

I found a way to include childB type docs.
I combine the following query with above query (has_child on childA type) in a filter query to get childB docs also. I am not really sure if its a good way though(thinking about performance)
{
"query":{
"bool":{
"should":[
{
"bool":{
"must_not":[
{
"has_child":{
"type":"ChildB",
"query":{
"match_all":{}
},
"inner_hits":{}
}
}
]
}
},
{
"has_child":{
"type":"ChildB",
"query":{
"match_all":{}
},
"inner_hits":{}
}
}
]
}
}
}

Related

How can I restrict the results from elasticsearch to only include parent-type documents?

I'm kinda stuck on this issue and struggling to find a solution:
I do have two types of entries in my shared Elasticsearch index, which are joined by a parent:child relationship.
I'd like to only receive documents of the "parent" type, but also include all "parent" documents which do not actually have child documents available.
Is there any way to implement this?
Best wishes,
Stefan
Below query is what you are looking for. I've made use of the Bool query
Let's say you have the below mapping for parent-child i.e. have question and its children are answer.
Mapping
PUT <your_index_name>
{
"mappings": {
"_doc": {
"properties": {
"my_join_field": {
"type": "join",
"relations": {
"question": "answer"
}
}
}
}
}
}
Query
POST <your_index_name>/_search
{
"query":{
"bool":{
"must":[
{ "term":{ "my_join_field":"question" }},
{
"bool":{
"must_not":[
{ "has_child":{
"type":"answer",
"query":{ "match_all":{} }
}
}
]
}
}
]
}
}
}
The above query would display all the parent documents i.e. question which doesn't have any children i.e.manswer.
Note that if you convert must_not into must in the above query, it would return you all the parent documents i.e. question which has children i.e answer ;)
Now if you want only parent documents. i.e. all the parent documents, your query would simply be in the below format:
Query for all parent documents
POST <your_index_name>/_search
{
"query":{
"bool":{
"must":[
{
"term":{
"my_join_field":"question"
}
}
]
}
}
}
OR it can be as simple as below:
POST <your_index_name>/_search
{
"query": {
"term": {
"my_join_field": "question"
}
}
}
Basically I've implemented Term Queries.
Let me know if it helps!

Elasticsearch get all parents with no children

Originally I've been trying to get a list of parents and a single most recent child for each one of them. I've figured how to do that with the following query
{"query":
{"has_child":
{"inner_hits":
{"name": "latest", "size": 1, "sort":
[{"started_at": {"order": "desc"}}]
},
"type": "child_type",
"query": {"match_all": {}}
}
}
}
But the problem is — the results do not include parents with no children. Adding min_children: 0 doesn't help either. So I thought I could make a query for all parents with no children and combine those two in a single OR query. But I'm having trouble building such a query. Would appreciate any suggestions.
Here is your query:
{
"query":{
"bool":{
"should":[
{
"bool":{
"must_not":[
{
"has_child":{
"type":"child_type",
"query":{
"match_all":{}
}
}
}
]
}
},
{
"has_child":{
"inner_hits":{
"name":"latest",
"size":1, "sort":[{"started_at": {"order": "desc"}}]
},
"type":"child_type",
"query":{
"match_all":{}
}
}
}
]
}
}
}
Another point: just use must_not for has_child will not only show parents without child, but all the child(s) as well, because they all don't have any child...
So another limitation should be added in the bool query:
{
"query":{
"bool": {
"must_not": [
{
"has_child": {
"type": "<child-type>",
"query": {
"match_all": {}
}
}
}
],
"should": [
{
"term": {
"<the join field>": {
"value": "<parent-type>"
}
}
}
]
}
}
}

how to know which keywords matched in elasticsaearch

Say that I query:
POST /story/story/_search
{
"query":{
"bool":{
"should":[
{
"match":{
"termVariations":{
"query":"not driving",
"type":"boolean",
"operator":"AND"
}
}
},
{
"match":{
"termVariations":{
"query":"driving",
"type":"boolean",
"operator":"AND"
}
}
}
]
}
}
}
This query returned by one analyzer or another 3 documents.
How do I tell which should clause was matched? Can Elasticsearch return the matched phrase along with the result?
Thanks!
The best option here would be named queries.
You can name your query and the name of the queries that matched would be provided per document.
{
"query": {
"bool": {
"should": [
{
"match": {
"name.first": {
"query": "qbox",
"_name": "first"
}
}
},
{
"match": {
"name.last": {
"query": "search",
"_name": "last"
}
}
}
]
}
}
}
Thanks #keety! highlight was exactly what I was looking for!! :-)

multiple search conditions in one query in es and distinguish the items according to the conditions

For one case I need to put multiple search conditions in one query to reduce the number of queries we need.
However, I need to distinguish the returning items based on the conditions.
Currently I achieved this goal by using function score query, specifically: each condition is assigned with a score, and I can differentiate the results based on those scores.
However, the performance is not that good. Plus now we need to get the doc count of each condition.
So is there any way to do it? I'm thinking using aggregation, but not sure if I can do it.
Thanks!
update:
curl -X GET 'localhost:9200/locations/_search?fields=_id&from=0&size=1000&pretty' -d '{
"query":{
"bool":{
"should":[
{
"filtered":{
"filter":{
"bool":{
"must":[{"term":{"city":"new york"}},{"term":{"state":"ny"}}]
}
}
}
},
{
"filtered":{
"filter":{
"bool":{
"must":[{"term":{"city":"los angeles"}},{"term":{"state":"ca"}}]
}
}
}
}
]
}
}}'
Well to answer the first part of your question , names queries are the best.
For eg:
{
"query": {
"bool": {
"should": [
{
"match": {
"field1": {
"query": "qbox",
"_name": "firstQuery"
}
}
},
{
"match": {
"field2": {
"query": "hosted Elasticsearch",
"_name": "secondQuery"
}
}
}
]
}
}
}
This will return an additional field called matched_queries for each hit which will have the information on queries matched for that document.
You can find more info on names queries here
But this this information cant be used for aggregation.
So you need to handle the second part of your question in a separate manner.
Filter aggregation for each query type would be the idea solution here.
For eg:
{
"query": {
"bool": {
"should": [
{
"match": {
"text": {
"query": "qbox",
"_name": "firstQuery"
}
}
},
{
"match": {
"source": {
"query": "elasticsearch",
"_name": "secondQuery"
}
}
}
]
}
},
"aggs": {
"firstQuery": {
"filter": {
"term": {
"text": "qbox"
}
}
},
"secondQuery": {
"filter": {
"term": {
"source": "elasticsearch"
}
}
}
}
}
You can find more on filter aggregation here

Mixing bool and multi match/function score query

I'm currently doing a query that's a mix of multi match and function score. The important bit of the JSON looks like this:
"function_score":{
"query":{
"query_string":{
"query":"some query",
"fields":["id","name","strippedDescription","colourSearch","sizeSearch"]
}
}
}
However, I also want to include results that don't necessarily match the query but have a particular numeric value that's greater than 0. I think a bool query would do this, but I don't know how to use a bool query with a function score query.
I understand that a multi match query is just shorthand for a bool query, and I could expand out the multi match query into its bool counter-part, however, I then don't know how I would do function score within that.
Any ideas? I'm on version 1.1.0 by the way.
Figured it out! I was missing the fact that you can nest multi field queries within bool queries! My final solution looks like this:
{
"query":{
"function_score":{
"query":{
"bool":{
"should": [
{
"range": {
"allBoost": {
"gt": 0
}
}
},{
"multi_match":{
"query":"some search query",
"fields":[
"id",
"name",
"description",
"category"
]
}
}
]
}
},
"functions":[
{
"filter":{
"range": {
"allBoost": {
"gt": 0
}
}
},
"script_score":{
"script":"doc['allBoost'].value"
}
},
{
"filter":{
"range": {
"allBoost": {
"lte": 0
}
}
},
"script_score":{
"script":"_score"
}
}
],
"boost_mode": "replace"
}
}
}

Resources