Use OR instead of AND in GraphQL boolean expression query - graphql

I am populating a table using graph QL query :
The graphql query looks like :
const DESSERT_QUERY = gql`
query DESSERT_QUERY($where: dessert_bool_exp) {
dessert(where: $where) {
name
calories
fat
carbs
}
}
`;
Query Variables :
{"where":
{
"name": {
"_in": ["xyz"]
},
"calories": {
"_eq": 1
},
"fat": {
"_eq": 606
},
"carbs": {
"_eq": 1
},
}
}
How to implement an OR query.
Any guidance is appreciated. Thanks

The correct GraphQL Query Variables is :
{"where":
{
"name": {
"_in": ["xyz"]
},
"calories": {
"_eq": 1
},
"_or": [{"fat": {
"_eq": 606
}},
{"carbs": {
"_eq": 1
}}]
}
}

Related

How to filter results in graphql?

Let's say I have the following schema:
query Publications($id: ProfileId!) {
publications(
request: { profileId: $id }
) {
items {
typename
}
}
}
And I get a result like so:
{
"data": {
"publications": {
"items": [
{
"typename": "Article"
},
{
"typename": "Post"
},
{
"typename": "Post"
},
]
}
}
}
How do I filter my results so I only get the "typename": "Article"?
One way is to add a second optional parameter to your query:
query Publications($id: ProfileId!, $typename: String) {
publications(
request: { profileId: $id , typename: $typename}
) {
items {
typename
}
}
}
Then in your resolver, if you see that typename has a value, filter your results to match.

How to using aggregations with composite for elasticsearch-dsl

i am using aggregations and aggregation bucket accept one key value as default then i research and find it
"aggs" : {
"my_buckets": {
"composite" : {
"sources" : [
{ "category_pk": { "terms": { "field": "category.pk"} } },
{ "category_name": { "terms": {"field": "category.name" } } }
]
}
}
}
}
Above code result two keys , and _doc_count but i can't apply for elasticsearch-dsl
Someone help me
Thanks
I solved the problem,When We are using Composite
s = ProductDocument.search()
brand_name = A('terms', field='brand.name')
brand_pk = A('terms', field='brand.id')
brand_key_aggs = [
{'brand_pk': brand_pk},
{'brand_name': brand_name}
]
s.aggs.bucket('brand_terms', "composite", sources=brand_key_aggs)
Example Result
{
'key':{
'brand_pk':869,
'brand_name':'Uni Baby'
},
'doc_count':2
},

Elasticsearch malformed query, expected [END_OBJECT] but found [FIELD_NAME]

I'm using the elasticsearch client for doing some search query using constant_score and aggregations but it's throwing the exception:
[parsing_exception] [constant_score] malformed query, expected [END_OBJECT] but found [FIELD_NAME]
This is where I'm creating the query and calling the search function:
fetchData: function fetchFn(req, res, next) {
var model = new urlModel();
util.log('Fetching data from ES::');
var query = buildAggregateUrl(req.reqData);
// if (req.reqData['domain']) {
// var termFilter = { "term": { "domain": req.reqData.domain } };
// query.constant_score.filter.bool.must.push(termFilter);
// }
model.search({ query }, function (er, re) {
if (re) {
req.sendResult = re;
}
next(er);
});
function buildAggregateUrl(opts) {
var query = {
constant_score: {
filter: {
bool: {
must: [{
"range": {
"timestamp": {
"gte": opts.startTime,
"lte": opts.endTime
}
}
}]
}
}
},
aggs: {
success: {
scripted_metric: {
init_script: "params._agg.succ=0;",
map_script: "if(doc.status.value=='success'){params._agg.succ+=1}",
combine_script: "return params._agg.succ",
reduce_script: "int sum=0;for (a in params._aggs){sum+=a}return sum"
}
},
failure: {
scripted_metric: {
init_script: "params._agg.fail=0;",
map_script: "if(doc.status.value=='failure'){params._agg.fail+=1}",
combine_script: "return params._agg.fail",
reduce_script: "int sum=0;for (a in params._aggs){sum+=a}return sum"
}
}
}
};
return query;
}
}
And this is what the search function looks like:
es_model.prototype.search = function (opts, cb) {
var query = {
index: this.esConfig.index,
type: this.esConfig.type,
body: {query:opts.query}
};
console.log('Query ===> ',query);
this.client.search(query, cb);
}
I can't figure out where the problem is with the syntax.I tried wrapping the constant_score key withtin query as well but it doesn't seem to work.
You're simply missing a query element at the top level:
{
query: {
constant_score: {
filter: {
bool: {
must: [{
"range": {
"timestamp": {
"gte": opts.startTime,
"lte": opts.endTime
}
}
}]
}
}
}
},
aggs: {
success: {
scripted_metric: {
init_script: "params._agg.succ=0;",
map_script: "if(doc.status.value=='success'){params._agg.succ+=1}",
combine_script: "return params._agg.succ",
reduce_script: "int sum=0;for (a in params._aggs){sum+=a}return sum"
}
},
failure: {
scripted_metric: {
init_script: "params._agg.fail=0;",
map_script: "if(doc.status.value=='failure'){params._agg.fail+=1}",
combine_script: "return params._agg.fail",
reduce_script: "int sum=0;for (a in params._aggs){sum+=a}return sum"
}
}
}
}
Also note that your client code should look like this:
es_model.prototype.search = function (opts, cb) {
var query = {
index: this.esConfig.index,
type: this.esConfig.type,
body: opts.query
};
this.client.search(query, cb);
}

JS - client.bulk() results in not mapped documents

I have a template with a mapping like this:
"template" : "database*",
"mappings": {
"_default_" : {
"dynamic_templates" : [
{
// default string mapping
"string" : {
"match" : "*",
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw" : {
"type": "keyword"
}
}
}
}
},
]
}
}
The idea behind this template is to generate for every new field a "type : keyword" field for exact searches.
When adding documents (in an empty index using this template) with JS API client.index() everything works fine, this way i am able to query like:
{
"query": {
"match": {
"fooBar": "bla"
}
}
}
Or for exact searches like:
{
"query": {
"match": {
"fooBar.raw": "bla"
}
}
}
But adding documents (again empty index) in bulk with client.bulk() like this:
client.bulk({
body: [
// FIRST DOCUMENT
{ index: { _index: 'myindex', _type: 'mytype', _id: 1 } },
// the first document to index
{ fooBar: 'foo' },
// SECOND DOCUMENT
{ index: { _index: 'myindex', _type: 'mytype', _id: 2 } },
// the second document to index
{ fooBar: 'bar' },
(...)
]
}, function (err, resp) {
// ...
});
The same "raw" request results in an error:
"No mapping found for [fooBar.raw] (...)"
while:
{
"query": {
"match": {
"fooBar": "bla"
}
}
}
delivers results. This brings me to the conclusion, that the document is indeed indexed but the field "raw" has not been created.
Is that right? Is in fact bulk Indexing not using mapping?
How can I use bulk import and map the documents?
Thanks! :)

Elasticsearch multi date range aggregation using java api

I use elasticsearch 2.2 and I want to do some aggregations like this:
{
"bool":{
"must":[
{
"query_string":{
"default_field":"berid",
"query":"F600-HHP1"
}
},
{
"query_string":{
"default_field":"matnr",
"query":"91P9289AAZZ"
}
}
]
},
"size":0,
"aggs":{
"count_by_date_range":{
"date_range":{
"field":"zzupload",
"ranges":[
{
"from":"2016-03-01",
"to":"2016-03-06"
},
{
"from":"2016-03-07",
"to":"2016-03-13"
},
{
"from":"2016-03-14",
"to":"2016-03-20"
},
{
"from":"2016-03-21",
"to":"2016-03-27"
},
{
"from":"2016-03-28",
"to":"2016-04-03"
},
{
"from":"2016-04-04",
"to":"2016-04-10"
},
{
"from":"2016-04-11",
"to":"2016-04-17"
},
{
"from":"2016-04-18",
"to":"2016-04-24"
},
{
"from":"2016-04-25",
"to":"2016-05-01"
},
{
"from":"2016-05-02",
"to":"2016-05-08"
},
{
"from":"2016-05-09",
"to":"2016-05-15"
},
{
"from":"2016-05-16",
"to":"2016-05-22"
},
{
"from":"2016-05-23",
"to":"2016-05-29"
},
{
"from":"2016-05-30",
"to":"2016-06-05"
},
{
"from":"2016-06-06",
"to":"2016-06-12"
},
{
"from":"2016-06-13",
"to":"2016-06-19"
}
]
},
"aggs":{
"total_fcst_qty":{
"sum":{
"field":"zzamqtu"
}
}
}
}
}
}
I need to calculate the sum of quantity on date range("from":"2016-03-01", "to":"2016-03-06", ...).But it's look like elasticsearch java api didn't support multi date_range.Here is my code:
SearchRequestBuilder searchBuilder = esClient.prepareSearch(Elasticsearch_sap_material_fcst_Index)
.setTypes(Elasticsearch_material_fcst_Type)
.setQuery(sb.toString())
.addAggregation(AggregationBuilders.dateRange("count_by_date_range").field("zzupload")
.addRange("2016-03-01", "2016-03-06")
.subAggregation(AggregationBuilders.sum("total_fcst_qty")));
How to calculate multiple date range using java api?
Thanks
You can just add multiple ranges like you did with the REST API:
SearchRequestBuilder searchBuilder = esClient.prepareSearch(Elasticsearch_sap_material_fcst_Index)
.setTypes(Elasticsearch_material_fcst_Type)
.setQuery(sb.toString())
.addAggregation(AggregationBuilders.dateRange("count_by_date_range").field("zzupload")
.addRange("2016-03-01", "2016-03-06")
.addRange("2016-05-23", "2016-05-29")
.subAggregation(AggregationBuilders.sum("total_fcst_qty")));
If you have a look at the source code, you can see that each call to addRange appends the new range to a list of ranges.

Resources