Elastic search returning wrong results - elasticsearch

I am running a query against elastic search but the results returned are wrong. The idea is that I can check against a range of fields with individual queries. But when I pass the following query, items which don't have the included lineup are returned.
query: {
bool: {
must: [
{match:{"lineup.name":{query:"The 1975"}}}
]
}
}
The objects are events which looks like.
{
title: 'Glastonbury'
country: 'UK',
lineup: [
{
name: 'The 1975',
genre: 'Indie',
headliner: false
}
]
},
{
title: 'Reading'
country: 'UK',
lineup: [
{
name: 'The Strokes',
genre: 'Indie',
headliner: true
}
]
}
In my case both of these events are returned.
The mapping can be seen here:
https://jsonblob.com/567e8f10e4b01190df45bb29

You need to use match_phrase query, match query is looking for either The or 1975 and it find The in The strokes and it gives you that result.
Try
{
"query": {
"bool": {
"must": [
{
"match": {
"lineup.name": {
"query": "The 1975",
"type": "phrase"
}
}
}
]
}
}
}

Related

elasticsearch search - search multiple fields

I am new to elastic search and I am trying to search my index that has the following properties:
// user index
{
profile: {
name: string,
description: string,
city: string
state: string
},
services: [
{
serviceName: string
},
{
serviceName: string
},
{
serviceName: string
},
...
]
}
I am trying to combine my query_string and nested, but I cannot seem to get it to work.
body: {
query: {
query_string: {
query: `*${searchTerm}*`,
fields: [
// these profile fields work
'profile.name',
'profile.description',
'profile.city',
'profile.state',
// doesnt work, need to use nested
'services.serviceName'
]
},
// if i use nested here, elasticsearch throws error
// can I combine these two queries like this?
nested: {
}
}
}
I cannot find any good examples to have both a nested AND query_string search query.
Anyone have any suggestions?
Anything helps, even links to good docs / examples for the thing I am trying to do.
You can combine query_string and nested query, using the boolean query
{
"query": {
"bool": {
"must": [
{
"query": {
"query_string": {
"query": "search term",
"fields": []
}
}
},
{
"query": {
"nested": {
"path": "services",
"query": {
"services.serviceName": "blue"
}
}
}
}
]
}
}
}

Elasticsearch: Full match of query value from beginning to end of field

I have problem with full match querying of field value. title and gender - fields of indexed docs
query: {
query_string: {
query: "box AND gender:\"women\"",
default_field: "title"
}
}
I use double quotes to match full query for gender. But if there is gender "men,women" with title 'box' it also will be in results. I know, that elasticsearch does not support regexp characters ^ and $ for beginning and end of the string, so I couldn't make /^women$/.
What do I need to do if I want docs matching only 'women' gender, not 'men,women' ?
Q:
What do I need to do if I want docs matching only 'women' gender, not 'men,women' ?
For exact searches you should use a terms query rather than a fulltext-search query like the query_string. So to get all documents that matches exactly gender == women you should do it like so:
GET your-index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"gender.keyword": {
"value": "women"
}
}
}
]
}
}
}
Please be aware that this query assumes that the gender-field is also mapped as a keyword.
To complete the query you would add another must-clause to get all documents that have box in the title field women as the value of the gender-field.
GET your-index/_search
{
"query": {
"bool": {
"must": [
{
"term": {
"gender.keyword": {
"value": "women"
}
}
},
{
"match": {
"title": "box"
}
}
]
}
}
}
Thank you apt-get_install_skill. Keyword did the work, but with some addings.
Summary this is solution:
query: {
bool: {
must: {
query_string: {
query: "box",
default_field: "title"
}
},
filter: {
bool: {
should: [
{term: {"gender.keyword": "women"}}
]
}
}
}
}
I need should as array for searching multiple genders if I will need it. For example, some docs have unisex gender, such as 'women,men'
Example with multiple genders:
query: {
bool: {
must: {
query_string: {
query: "box",
default_field: "title"
}
},
filter: {
bool: {
should: [
{term: {"gender.keyword": "women"}},
{term: {"gender.keyword": "kids"}}
#summary it may be gender 'girls'
]
}
}
}
}

Elasticsearch custom function score

i am trying to do a search with custom functions to modify document score.
I have a mapping with specialities stored inside a hospital and every speciality has a priority with it:
Something like:
hospital:{
name: 'Fortis',
specialities: [
{
name: 'Cardiology',
priority: 10
},
{
name: 'Oncology',
priority: 15
}
]
}
Now i have a function score :
functions: [{
filter: {terms: {'specialities.name' => params[:search_text]}},
script_score: {script: "_score * doc['specialities.priority'].value"}
},
I have a filter query to match the search text to any speciality.
Like if i search Oncology, it will match and then I have specified a script_score to take priority of that speciality and add it to final score of document.
But, it is taking the priority of the first speciality it encounters that is 10 and a score of 1 for the filter matched and the end score is 11 not 21 (priority of oncology + 1 for filter match)
I solved it using nested mapping in elasticsearch.
Lucene internally has no concept of storing object mappings by default, so if I am looking to store priority for every speciality I should have a mapping like this:
hospital: {
properties: {
specialities: {
type: nested,
properties: {
name: {
type: 'string'
}priority: {
type: 'long'
}
}
}
}
}
Reference: https://www.elastic.co/guide/en/elasticsearch/reference/2.0/nested.html
After that, I was able to define function score with nested query and my query looks like this:
"query": {
"filtered": {
"query": {
"bool": {
"must": [
{
"nested": {
"path": "specialities",
"query": {
"function_score": {
"score_mode": "sum",
"boost_mode": "sum",
"filter": {
"terms": {
"specialities.name.raw": ["Oncology"]
}
},
"functions": [
{
"field_value_factor": {
"field": "specialities.priority"
}
}
]
}
}
}
}
]
}
}
}
}

Elasticsearch match nested field against array of values

I'm trying to apply a terms query on a nested field using mongoid-elasticsearch and ElasticSearch 2.0. This has come to be quite frustrating since the trial-error didn't pay off much and the docs on the subject are rather sparse.
Here is my query:
{
"query": {
"nested": {
"path": "awards",
"query": {
"bool": {
"must": [
{ "match": { "awards.year": "2010"}}
]
}
}
},
"nested":{
"path": "procuring_entity",
"query": {
"bool": {
"must": [
{ "terms": { "procuring_entity.country": ["ES", "PL"]}}
]
}
}
}
}
}
While "match" and "term", work just fine, when combined with the "terms" query it returns no results, even thought it should. My mappings looks like this:
elasticsearch!({
prefix_name: false,
index_name: 'documents',
index_options: {
mappings: {
document: {
properties: {
procuring_entity: {
type: "nested"
},
awards: {
type: "nested"
}
}
}
}
},
wrapper: :load
})
If "nested" doesn't count as analyzer (which as far as I know doesn't), than there's no problem with that. As for the second example,I don't think it's the case since the array of values that it's matched against comes from exterior.
Is terms query possible on nested fields? Am I doing something wrong?
Is there any other way to match a nested field against multiple values?
Any thoughts would be much appreciated.
I think you would need to change your mappings for your nested types for this - the terms query only works on not_analyzed fields. If you update your mapping to something like:
elasticsearch!({
prefix_name: false,
index_name: 'documents',
index_options: {
mappings: {
document: {
properties: {
procuring_entity: {
type: 'nested',
properties: {
country: {
'type': 'string',
'index': 'not_analyzed'
}
}
},
awards: {
type: 'nested'
}
}
}
}
},
wrapper: :load
})
I think the query should work if you do that.

Elasticsearch: Get report of unmatched should elements in a bool query

I'm looking for a way to get a report of unmatched should querys and display it.
For instance I have two user objects
User 1:
{
"username": "user1"
"docType": "user"
"level": "Professor"
"discipline": "Sciences"
"sub-discipline": "Mathematical"
}
User 2:
{
"username": "user1"
"docType": "user"
"level": "Professor"
"discipline": "Sciences"
"subDiscipline": "Physics"
}
When I do a bool query where the matching discipline is in must query and the sub-discipline is in the should query
bool:
must: [{
term: { "doc.docType": "user" }
},{
term: { "doc.level": "professor" }
},{
term: { "doc.discipline": "sciences" }
}],
should: [{
term: { "subDiscipline": "physics" }
}]
How can I get the unmatched elements in my result like that:
Result 1: user1 match 100%
Result 2: user2 match 70% (unmatch subdiscipine "physics")
I had a look into the explainApi but the result doesn't seems to be provided for that use case and seems very complicated to parse.
You will need to use named queries for this.
Using the same , create a bool query like below -
{
"query": {
"bool": {
"must": [
{
"match": {
"SourceName": {
"query": "CNN",
"_name": "sourceMatch"
}
}
},
{
"match": {
"author": {
"query": "qbox.io",
"_name": "author"
}
}
}
]
}
}
}
In the result section , it will tell which all named queries matched.
You can use this information to fabricate the stats you are looking for.

Resources