Match query with multiple values - json

I have a list of values and I want all documents that have any of these values in their product_code field.
I tried this, but even though it doesn't give an error, it only gives me one of the documents:
"query": {
"match": {
"product_code": {
"query": ["ABC 4", "ABC 5"]
}
}
}
So I'm basically looking for the functionality of the terms filter, but with analysis.
Of course I could do:
"bool": {
"should": [
{
"query": {
"match": {
"product_code": "ABC 4"
}
}
},
{
"query": {
"match": {
"product_code": "ABC 5"
}
}
}
]
}
but this gets rather verbose for long lists.
product_code is defined like this:
"product_code": {
"type": "string",
"analyzer": "product_code",
}
with the product_code analyzer:
"product_code": {
"type": "custom",
"filter": [
"lowercase",
"trim"
],
"tokenizer": "keyword"
}

There isn't an equivalent of the terms query for match AFAIK. Another option is the query_string which is less verbose:
{
"query": {
"query_string": {
"default_field": "product_code",
"query": "\"ABC 4\" OR \"ABC 5\""
}
}
}
http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-query-string-query.html

I might be missing something, but how about:
{
"constant_score" : {
"filter" : {
"terms" : { "product_code" : ["ABC 4", "ABC 5"]}
}
}
}
Could this be what you're looking for?

Related

must match URL address returning a lot of documents - Elasticsearch

I'm simply trying to check how many documents have the same link value. There is something weird going on.
Let's say one or more documents has this link value: https://twitter.com/someUser/status/1288024417990144000
I search for it using this JSON query:
/theIndex/_doc/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"link": "https://twitter.com/someUser/status/1288024417990144000"
}
}
]
}
}
}
It returns documents 522 of 546, with the first document being the correct one. It acts more like a query_string than a must match
If I search another more unique field like sha256sum:
{
"query": {
"bool": {
"must": [
{
"match": {
"sha256sum": "dad06b7a0a68a0eb879eaea6e4024ac7f97e38e6ac2b191afa7c363948270303"
}
}
]
}
}
}
It returns 1 document like it should.
I've tried searching must term aswell, but it returns 0 documents.
Mapping
{
"images": {
"aliases": {},
"mappings": {
"properties": {
"sha256sum": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"link": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
}
},
"settings": {
"index": {
"number_of_shards": "1",
"provided_name": "images",
"creation_date": "1593711063075",
"analysis": {
"filter": {
"synonym": {
"ignore_case": "true",
"type": "synonym",
"synonyms_path": "synonyms.txt"
}
},
"analyzer": {
"synonym": {
"filter": [
"synonym"
],
"tokenizer": "keyword"
}
}
},
"number_of_replicas": "1",
"uuid": "a5zMwAYCQuW6U4R8POiaDw",
"version": {
"created": "7050199"
}
}
}
}
}
I wouldn't think such a simple issue would be so hard to fix. Am I just missing something right in front of my eyes?
Does anyone know what might be going on here?
Even though I don't see the link field in your mapping (is it source?), I suspect it is a text field and text fields are analyzed. If you want to perform an exact match, you need to match on the link.keyword field and it's going to behave like you expect:
{
"query": {
"bool": {
"must": [
{
"match": {
"link.keyword": "https://twitter.com/someUser/status/1288024417990144000"
^
|
add this
}
}
]
}
}
}

Elasticsearch - Query on array for matching multiple objects in the array

I am trying to write a query that will match a document with a nested object that is an array of objects. Example :
{"ListName" : "List 1", "Fruits": [ { "name" : "Apple"}, {"name": "Orange"}, {"name" : "banana"} ] }
I would like to write a query were I get the document above based on the names inside the Fruits array, e.g. Apple and Orange.
What I currently have matches names with both Apple and Orange in the same name field rather than each object.
{
"query": {
"nested": {
"path": "Fruits",
"query": {
"bool": {
"must": [
{
"term": {
"Fruits.name": "Apple"
}
},
{
"match": {
"Fruits.name": "Orange"
}
}
]
}
}
}
}
}
You need to make two different nested queries in a bool/must query instead, like this:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "Fruits",
"query": {
"term": {
"Fruits.name": "Apple"
}
}
}
},
{
"nested": {
"path": "Fruits",
"query": {
"match": {
"Fruits.name": "Orange"
}
}
}
}
]
}
}
}

Search On Nested Field If Query Parameter Equal To True

I need to search for a nested field like following:
"bool": {
"should": {
"nested": {
"path": "partnerData",
"query": {
"query_string": {
"query": "Dimmi",
"fields": ["partnerData.partnerName"]
}
}
}
}
}
What I need to do now is to make this filter optional from a query parameter.
If online-booking: true apply this filter, if online-booking: false do not apply the filter.
How can I achieve this?
Thanks,
Marco
You should use multiple bool queries.
First query make sure that online-booking is false, second make sure that its true and second condition is also true. At least one query must match to be returned
{
"bool": {
"should": [
{
"term": {
"online-booking": false
}
},
{
"bool": {
"must": [
{
"term": {
"online-booking": true
}
},
{
"nested": {
"path": "partnerData",
"query": {
"query_string": {
"query": "Dimmi",
"fields": [
"partnerData.partnerName"
]
}
}
}
}
]
}
}
]
}
}
"bool": {
"should": [{
"nested": {
"path": "partnerData",
"query": {
"query_string": {
"query": "Dimmi",
"fields": ["partnerData.partnerName"]
}
}
}
},{
"query_string": {
"query": "$negate-online-booking$",
"default_field": "name"
}
}]
}
If negate-online-booking is different from _exists_:name filter will be applied. If its value is equal to _exists_:name filter will not applied.
If there is a better way to achieve the same result please suggest it.

Elastic search 2.1 query to get only a element from an array

I have below mapping, I want to access a property of imageMap instead of all collection.
"imageMap": {
"properties": {
"item1": {
"type": "long"
},
"item2": {
"type": "string"
},
"item3": {
"type": "string"
}
}
}
Below is the sample data
imageMap": [
{
"item1": 20893,
"item2": "ImageThumbnail_100_By_44",
"item3": "/9j/4AAQSkZJRg"
},
{
"item1": 20893,
"item2": "ImageThumbnail_400_By_244",
"item3": "/9j/4AAQSkZJRgABAQEAYABgAAD/2w"
}
]
Below is my Query that is not working. Any help is appreciated. Thank you in advance.
Updated:
{
"_source": {
"include": [
"imageMap"
]
},
"query": {
"bool": {
"must": [
{
"term": {
"imageMap.item1": {
"value": 20893
}
},
"term": {
"imageMap.item2": {
"value": "imagethumbnail_100_by_44"
}
}
}
]
}
}
}
Expected Result is below only single element of imageMap, but i am getting array :
"_source": {
"imageMap": [
{
"item2": "ImageThumbnail_100_By_44",
"item1": 20893,
"item3": "/9j/4AAQSkZJRgABAQ"
}
]
}
If you only wan to get a single element from the imageMap array, you need to map imageMap as a nested object like this:
"imageMap": {
"type": "nested", <--- add this
"properties": {
"item1": {
"type": "long"
},
"item2": {
"type": "string"
},
"item3": {
"type": "string"
}
}
}
Then you need to wipe your index and re-build it from scratch with this new mapping.
In the end, you'll be able to retrieve only a specific element using a nested inner_hits query:
{
"_source": false,
"query" : {
"nested" : {
"path" : "imageMap",
"query" : {
"match" : {"imageMap.item2" : "ImageThumbnail_100_By_44"}
},
"inner_hits" : {}
}
}
}
Your query is not working because you are using term query which does not do any analysis on your search string. Since you have not specified any analyzer in mapping ImageThumbnail_100_By_44 is stored as imagethumbnail_100_by_44 because it is analyzed by standard analyzer
Depending on your requirement you could either map your item2 as "index : not_analyzed" and your query will work fine or you could use match query which will do analysis.
{
"_source": {
"include": [
"imageMap"
]
},
"query": {
"bool": {
"must": [
{
"match": {
"imageMap.item2": {
"query": "ImageThumbnail_100_By_44"
}
}
}
]
}
}
}
Please go through this document to have better understanding of analysis process

filter '_index' same way as '_type' in search across multiple index query elastic search

I have two indexes index1 and index2 and both has two types type1 and type2 with same name in elastic search.(please assume that we have valid business reason behind it)
I would like to search index1 - type1 and index2 -type2
here is my query
POST _search
{
"query": {
"indices": {
"indices": ["index1","index2"],
"query": {
"filtered":{
"query":{
"multi_match": {
"query": "test",
"type": "cross_fields",
"fields": ["_all"]
}
},
"filter":{
"or":{
"filters":[
{
"terms":{
"_index":["index1"], // how can i make this work?
"_type": ["type1"]
}
},
{
"terms":{
"_index":["index2"], // how can i make this work?
"_type": ["type2"]
}
}
]
}
}
}
},
"no_match_query":"none"
}
}
}
You can use the indices, type in a bool filter to filter on type and index
The query would look something on these lines :
POST index1,index2/_search
{
"query": {
"filtered": {
"query": {
"multi_match": {
"query": "test",
"type": "cross_fields",
"fields": [
"_all"
]
}
},
"filter": {
"bool": {
"should": [
{
"indices": {
"index": "index1",
"filter": {
"type": {
"value": "type1"
}
},
"no_match_filter": "none"
}
},
{
"indices": {
"index": "index2",
"filter": {
"type": {
"value": "type2"
}
},
"no_match_filter": "none"
}
}
]
}
}
}
}
}
Passing the index names in the url example : index1,index2/_search is a good practice else you risk executing query across all indices in the cluster.