I tried to query track records which either title or lyric contain "cat". But only record return if both title and lyric have cat. May I know how to query by OR operator.
Query
query Tracks($where: TrackWhereInput) {
tracks(where: $where) {
id
title
lyric
youtube_url
mp3_url
}
}
Variables
{
"where": {
"OR": [
{
"title": {
"contains": "cat"
},
"lyric": {
"contains": "cat"
}
}
]
}
}
You must pass conditions to OR operator in different objects. You've passed an object array but both conditions are in same object. Conditions in same object use AND operator.
Your fixed code would be:
{
"where": {
"OR": [
{
"title": {
"contains": "cat"
},
},
{
"lyric": {
"contains": "cat"
}
}
]
}
}
Related
I have a situation where I need to do elastic search based on multi-field. For Example: I have multiple fields in my postindex and I want to apply condition on four these fields (i.e. userid, channelid, createat, teamid) to meet my search requirement. When value of all these fields matched then search query displays results and if one of these is not match with values in postindex then it display no result.
I am trying to make a multifield search query for go-elasticsearch to search data from my post index. For the searcquery result four field must match otherwise it display 0 hit/no-result.
So, I think you need to write a following query :
GET postindex/_search
{
"query": {
"bool": {
"minimum_should_match": 1,
"should": [
{
"bool": {
"must": [
{
"term": {
"userid": {
"value": "mcqmycxpyjrddkie9mr13txaqe"
}
}
},
{
"term": {
"channelid": {
"value": "dnoihmrinins3qrm6bb9175ume"
}
}
},
{
"range": {
"createat": {
"gt": 1672909114890
}
}
}
]
}
},
{
"term": {
"teamid": {
"value": "qomrg11o8b8ijxoy8hrcnweoay"
}
}
}
]
}
}
}
In here, there is a bool query with should in parent scope, which is like OR. And inside the should there is another bool query with must which is like AND. We can also write the query shorter, but this will be better for you to understand.
I'm adding documents with the following strutucte
{
"proposta": {
"matriculaIndicacao": 654321,
"filial": 100,
"cpf": "12345678901",
"idStatus": "3",
"status": "Reprovada",
"dadosPessoais": {
"nome": "John Five",
"dataNascimento": "1980-12-01",
"email": "fulanodasilva#fulano.com.br",
"emailValidado": true,
"telefoneCelular": "11 99876-9999",
"telefoneCelularValidado": true,
"telefoneResidencial": "11 2211-1122",
"idGenero": "1",
"genero": "M"
}
}
}
I'm trying to perform a search with multiple field values.
I can successfull search for a document with a specific cpf atribute with the following search
{
"query": {
"term" : {
"proposta.cpf" : "23798770823"
}
}
}
But now I need to add an AND clause, like
{
"query": {
"term" : {
"proposta.cpf" : "23798770823"
,"proposta.dadosPessoais.dataNascimento": "1980-12-01"
}
}
}
but it's returning an error message.
P.S: If possible I would like to perform a search where if the field doesn't exist, it returns the document that matches only the proposta.cpf field.
I really appreciate any help.
The idea is to combine your constraints within a bool/should query
{
"query": {
"bool": {
"should": [
{
"term": {
"proposta.cpf": "23798770823"
}
},
{
"term": {
"proposta.dadosPessoais.dataNascimento": "1980-12-01"
}
}
]
}
}
}
I have the following query to add fuzziness to my search. However, I now realize that the match query doesn't consider the order of the words in the search string, as the match_phrase does. However, I can't get match_phrase to give me results with fuzziness. Is there a way to tell match to consider the order and distance between words?
{
"query": {
"match": {
"content": {
"query": "some search terms like this",
"fuzziness": 1,
"operator": "and"
}
}
}
}
Eventually figured out that I needed to use a combination of span queries, which give an excellent amount of fine tuning to fuzziness and slop. I needed to add a function to manually tokenize my phrases and add to the "clauses" array in an programmatically:
{"query":
{
"span_near": {
"clauses": [
{
"span_multi": {
"match": {
"fuzzy": {
"content": {
"fuzziness": "2",
"value": "word"
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"content": {
"fuzziness": "2",
"value": "another"
}
}
}
}
}
],
"slop": 1,
"in_order": "true"
#econgineer Excellent post.
I wanted to try this for an ES query we are working on - but I am too lazy to keep doing the JSON data....
I think this code works... strangely it causes jq to complain but ElasticSearch work....
import json
import pprint
from collections import defaultdict
nested_dict = lambda: defaultdict(nested_dict)
query=nested_dict()
query['span_near']['clauses']=list()
query['slop']='1'
query['in_order']="true"
words=['what','is','this']
for w in words:
nest = nested_dict()
nest["span_multi"]["match"]["fuzzy"]["msg"]["fuzziness"]["value"]=w
nest["span_multi"]["match"]["fuzzy"]["msg"]["fuzziness"]["fuzziness"]="2"
json.dumps(nest)
query['span_near']['clauses'].append(json.loads(json.dumps(nest)))
pprint.pprint(json.loads(json.dumps(query)))
If you beautify the output by
cat t2.json | tr "\'" "\"" | jq '.'
You should see something like
{
"in_order": "true",
"slop": "1",
"span_near": {
"clauses": [
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "what"
}
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "is"
}
}
}
}
}
},
{
"span_multi": {
"match": {
"fuzzy": {
"msg": {
"fuzziness": {
"fuzziness": "2",
"value": "this"
}
}
}
}
}
}
]
}
}
And then to query ES it is just a normal
curl --silent My_ES_Server:9200:/INDEX/_search -d #t2.json
Many thanks for the initial guidance, I hope someone else find this of use.
Indeed, an excellent question and answer.
I'm surprised that this 'fuzzy phrase match' doesn't have support out of the box.
Here's a tested NodeJS code that generates the fuzzy phrase match (multi clause) query block, in the context of a multi search (msearch), but that should work just the same with a single search.
Usage:
const queryBody = [
{ index: 'YOUR_INDEX' },
createESFuzzyPhraseQueryBlock('YOUR PHRASE', 'YOUR_FIELD_NAME', 2)
];
client.msearch({
body: queryBody
})
Functions:
const createESFuzzyPhraseClauseBlock = (word, esFieldName, fuzziness) => {
const clauseBlock = {
"span_multi": {
"match": {
"fuzzy": {
[esFieldName]: {
"fuzziness": fuzziness,
"value": word
}
}
}
}
});
return clauseBlock;
};
const createESFuzzyPhraseQueryBlock = (phrase, esFieldName, fuzziness) => {
const clauses = phrase.split(' ').map(word => createESFuzzyPhraseClauseBlock(word, esFieldName, fuzziness));
const queryBlock =
{
"query":
{
"span_near": {
"clauses": clauses,
"slop": 1,
"in_order": "true"
}
}
};
return queryBlock;
};
Consider also mixing the queries, for me basic query looked like this - for phrases of length 2 I've used prefix query and for the rest I've used match query with fuziness set to AUTO.
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
}
}
]
}
}
}
Trying to sort query results now. Neither of the queries below works:
{
"sort": [
{
"name": {
"order": "asc"
}
}
],
"query": {
"match_all": {}
}
}
{
"query": {
"match_all": {}
},
"sort": [
{
"name": {
"order": "asc"
}
}
]
}
even though they seem to be valid, according to the (documentation). What am I missing here? And by the way, does the order of query parts matters at all in Elastic?
i have faced same case.If your name field mapped as string and anlayzed then query never works. Use multi field type where you can map name twice, one as string and analyzed and another as string and not analyzed. For Ex
'user_id' =>array('type'=>'integer'),
'name' =>array(
'type'=>'multi_field',
'fields'=>array(
'name'=>array('type'=>'string','index'=>'analyzed'),
'sort_name'=>array('type'=>'string','index'=> 'not_analyzed')
)
)
using above mapping, you can search on name field and u can sort using sort_name.
{
'query': {
'query_string':{'query':'user_name*','fields':['name']}
},
'sort':[
{
'name.sort_name': {
'order': 'asc'
}
}
]
}
Reference Link :
1) http://awesomism.co.uk/536336#
2) http://blog.wiercinski.net/2011/uncategorized/elasticsearch-sorting-on-string-types-with-more-than-one-value-per-doc-or-more-than-one-token-per-field/