Elastic Search: matching documents whose array contains this field - elasticsearch

I have a document similar to this:
{
name: "bob",
contains: ["a", "b", "c"]
},
{
name: "mary",
contains: ["a", "b"]
},
{
name: "Jason",
contains: ["b"]
}
I want to make a query to find all of the people who contain "a" (bob and mary). How can I write the query?
EDIT:
Current query:
query: {
bool: {
must: [
{ match: { exists: "yes" }},
{ term: {contains: "a"}}
],
must_not: [
{ match: { status: "removed"}}
]
}
}

A term filter/query on the contains field, such as {term: {contains: "a"}} will get you what you need. Assuming that you want to just match any document which satisfies that criteria, the full query would look something like:
{
"query": {
"filtered": {
"filter": {
"term": {
"contains": "a"
}
}
}
}
}
This works because arrays of values are indexed individually, and a term query will find documents which contain an array containing that value if the field queried is a list.

Related

AND search in an array of strings 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"
}
}
]

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 match against filter only

We have a multi-tenant index and need to perform queries against the index for a single tenant only. Basically, for all documents that match the filter, return any documents that match the following query, but do not include documents that only match the filter.
For example, say we have a list of documents document like so:
{ _id: 1, account_id: 1, name: "Foo" }
{ _id: 2, account_id: 2, name: "Bar" }
{ _id: 3, account_id: 2, name: "Foo" }
I thought this query would work but it doesn't:
{
"bool": {
"filter": { "term": { "account_id": 2 } },
"should": [
{ "match": { "name": "Foo" }
]
}
}
It returns both documents matching account_id: 2:
{ _id: 3, account_id: 2, name: "Foo", score: 1.111 }
{ _id: 2, account_id: 2, name: "Bar", score: 0.0 }
What I really want is it just to return document _id: 3, which is basically "Of all documents where account_id is equal to 2, return only the ones whose names match Foo".
How can I accomplish this with ES 6.2? The caveat is that the number of should and must match conditions are not always known and I really want to avoid using minimum_should_match.
Try this instead: simply replace should by must:
{
"bool": {
"filter": { "term": { "account_id": 2 } },
"must": [
{ "match": { "name": "Foo" }
]
}
}

Elastic search returning wrong results

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"
}
}
}
]
}
}
}

elasticsearch wildcard index type

In elasticsearch, is it possible to define wildcard types (index)?
For example: I have an index named miner and have types P1, P2, N1, N2.
I want to search index: miner with all types starting with 'P'. I tried 'P*' and does not work. Is it possible?
client.search({
index: 'miner',
type: 'P*',
Thank you
You need a prefix query for field _type. My example below demonstrates the prefix query together with whatever else you would like to search your index:
GET /miner/_search
{
"query": {
"bool": {
"must": [
{
"prefix": {
"_type": {
"value": "test"
}
}
},
{
"match": {
"name": "bob"
}
}
]
}
}
}

Resources