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"
}
}
}
}
]
}
}
}
Related
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'
]
}
}
}
}
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"
}
}
]
}
}
}
}
]
}
}
}
}
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"
}
}
}
]
}
}
}
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.
I have a filtered query like this
query: {
filtered: {
query: {
bool: {
should: [{multi_match: {
query: #query,
fields: ['title', 'content']
}
},{fuzzy: {
content: {
value: #query,
min_similarity: '1d',
}
}}]
}
},
filter: {
and: [
type: {
value: #type
}]
}}}
That works fine if #type is a string, but does not work if #type is an array. How can I search for multiple types?
This worked, but I'm not happy with it:
filter: {
or: [
{ type: { value: 'blog'} },
{ type: { value: 'category'} },
{ type: { value: 'miscellaneous'} }
]
}
I'd love to accept a better answer
You can easily specify multiple types in your search request's URL, e.g. http://localhost:9200/twitter/tweet,user/_search, or with type in the header if using _msearch, as documented here.
These are then added as filters for you by Elasticsearch.
Also, you usually want to be using bool to combine filters, for reasons described in this article: all about elasticsearch filter bitsets
This worked for me:
Within the filter parameter, wrap multiple type queries as should clauses for a bool query
e.g
{
"query": {
"bool": {
"must": {
"term": { "foo": "bar" }
},
"filter": {
"bool": {
"should": [
{ "type": { "value": "myType" } },
{ "type": { "value": "myOtherType" } }
]
}
}
}
}
}
Suggested by dadoonet in the Elasticsearch github issue Support multiple types in Type Query