AND search in an array of strings Elasticsearch - elasticsearch

Let's say I have an array field containing strings in Elasticsearch documents.
Let the array in one of the documents be
mArray1: ["string1", "string2", "string3", "string4"]
mArray2: ["string1", "string7", "string11"]
I want a query to search the document which has both "string1" and "string2", i.e. it should return mArray1. Here is what I am using which uses OR filtering.I am also matching for another field which should be compulsory
query: {
bool: {
filter: [
{
range: {
"math.score": {
gte: 80
}
}
},
{
multi_match: {
query: "name1",
fields: ["name", "full_name"],
type: "phrase_prefix"
}
}
],
must: [
{
terms: {
"arrayField": ["string1", "string2"]
}
}
]
}
}

terms matches any of the values specified, you want to match documents that have both string1 and string2 to, then you need to two term queries in must:
"must" : [
{
"term" : {
"arrayField" : "string1"
}
},
{
"term" : {
"arrayField" : "string2"
}
}
]

Related

Elasticsearch - use a field match to boost only and not to fetch the document

I have a query phrase that needs to match in either of the fields - name, summary or description or the exact match on the name field.
Now, I have one more new field brand. Match in this field should be used only to boost results. Meaning if there is a match only in the brand field, the doc should not be in the result set.
To solve the without brand I have the below query:
query: {
bool: {
minimum_should_match: 1,
should: [
multi_match:{
query : "Cadbury chocklate milk",
fields : [name, summary, description]
},
term: {
name_keyword: {
value: "Cadbury chocklate milk"
}
}
]
}
}
This works fine for me.
How do I fetch the data using the same query but boost docs that have brand:cadbury, without increasing the recall set(match based on brand:cadbury).
Thanks!
Using a bool inside must should work for you.
multi_match has multiple types and for phrase you have to use type:phrase.
{
"query": {
"bool": {
"must": [
{ "bool" :
{ "should" : [ {
"multi_match" :{
"type" : "phrase",
"query" : "Cadbury chocklate milk",
"fields" : ["name", "summary", "description"]
} }, {
"term": {
"name_keyword": {
"value": "Cadbury chocklate milk"
} }
}
]
}
}
],
"should" : {
"term" : {
"brand" : {
"value" : "cadbury"
}
}
}
}
}

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 wildcard matching on multiple fields

I have some string s that I want to match with at least one of two fields, as a substring (s). So for example, if I have the string 456, I would want to search for any entries where in at least one of two specified fields, there exists the string 456. So if field1 had 1234567, it would match, or if field2 had 34567, it would match. Below is an one of the ways I've tried to do it so far, but no luck.
query: {
bool: {
should: { wildcard: { field1: "*" + input + "*"}},
should: { wildcard: { field1: "*" + input + "*"}}
}
}
I have also tried
query: {
query_string: "*" + input + "*",
fields: ["field1", "field2"]
}
I think what you need is:
{
"query": {
"bool": {
"should": [
{
"wildcard": {
"field1": "*"+"input"+"*"
}
},
{
"wildcard": {
"field2": "*"+"input"+"*"
}
}
]
}
}
}

Elasticsearch: filter documents on missing field unless other field exists

I am doing an Elasticsearch query, that filters out all document, where a specific field is missing via
query: {
filtered: {
filter: {
bool: {
should: {
bool: {
must: {
term: 'someCondition'
},
must_not: {
missing: {field: 'somefield'}
}
}
}
}
}
}
}
This works as expected. Now I need to make this missingfilter conditional, so that it will only match, if another field does not exist.
I have tried converting my must_not to a should like this:
should: {
missing: {field: 'somefield'},
exists: {'field': 'somotherfield'}
}
But that does not seem to work.
To clarify: "SELECT * from docs WHERE (somefield IS NOT NULL OR someotherfield IS NOT NULL)"
Try query like this:
"filters" : [ {
"missing" : {
"field" : "somefield"
}
}, {
"not" : {
"filter" : {
"missing" : {
"field" : "somotherfield"
}
}
}
} ]

In Elasticsearch how to use multiple term filters when number of terms are not fixed they can vary?

I know for using multiple term filters one should use bools but the problem here is that i dont know how many terms there gonna be for example i want to filter results on strings with OR ("aa", "bb", "cc", "dd", "ee") now i want my searches that will contain any of the strings but the problem is that sometimes this array size will be 15 or 10 or 20 now how can i handle number of terms in filters my code is given below.
var stores = docs.stores; // **THIS IS MY ARRAY OF STRINGS**
client.search({
index: 'merchants',
type: shop_type,
body: {
query: {
filtered: {
filter: {
bool: {
must: [
{
// term: { 'jeb_no': stores }, // HERE HOW TO FILTER ALL ARRAY STRINGS WITH OR CONDITION
}
]
}
}
}
}, script_fields : {
"area": {
"script" : "doc['address.area2']+doc['address.area1']"
}
}
}
})
I think this will do. Use terms instead of term
{
"query": {
"bool": {
"must": [
{
"terms": {
"jeb_no": stores
}
}
]
}
}
}

Resources