How to filter results in graphql? - 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.

Related

Use OR instead of AND in GraphQL boolean expression query

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

is there a way to write a boolean query with different conditions in elasticsearch?

Ive setted up elasticsearch with a NodeJS Server and need a working boolean query that checks different conditions in the search. How to do that?
I am using mongoosastic(query DSL) with NodeJS and the following query to get the results
mapping Function
async function mapMongoToElastic() {
return new Promise((resolve, reject) => {
console.log("---------Mapping gets created---------");
Product.createMapping(
{
mappings: {
product: {
properties: {
ArtNumber: { type: "text" },
Title: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
},
DisplayPrice: { type: "double" },
CF_Deliverytime: { type: "text" },
Description_Short: { type: "text" },
MainCat: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
},
ItemCat: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
},
Deeplink1: { type: "text" },
Img_url: { type: "text" },
CF_img_url2: { type: "text" },
CF_img_url3: { type: "text" },
CF_Availability: { type: "text" },
CF_Productrating: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
},
CF_Discount: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
},
Shop: {
type: "text",
fields: {
keyword: {
type: "keyword"
}
}
}
}
}
}
},
function(err, mapping) {
if (err) {
console.log("error creating mapping (you can safely ignore this)");
console.log(err);
resolve(err);
} else {
console.log("X - ElasticSearch Mapping Created");
resolve(mapping);
}
}
);
});
}
Query function
async function asyncSearchWithOutFilter(query, from, to) {
return new Promise((resolve, reject) => {
Product.esSearch(
{
from: from,
size: to,
query: {
multi_match: {
query: query.suche,
fields: [ "Title^10", "ItemCat^5" ]
}
},
aggs: {
mainCats: {
terms: { field: "MainCat.keyword" }
},
itemCats: {
terms: { field: "ItemCat.keyword" }
},
itemShops: {
terms: {
field: "Shop.keyword"
}
}
}
},
{},
async (err, results) => {
if (err) throw err;
let res = await results;
/* console.log("-------------Total Hits---------------");
console.log(res.hits.total);
console.log("-----------------------------------------");
console.log("-------------Shops---------------");
console.log(res.aggregations.itemShops.buckets);
console.log("-----------------------------------------");
console.log("-------------Item-Categories---------------");
console.log(res.aggregations.itemCats.buckets);
console.log("-----------------------------------------"); */
resolve(res);
}
);
});
}
Expected results:
- Query for "TV"
Results:
Products with Title "TV" in
- if Category has "TV" also, rank it up higher.
Problem:
Smart-TV-Controller is also listed if searched for "TV", but not expected if someone is searching for a "TV"
help appreciated.
Seems like you are trying to get exact match. You already have keyword type sub-field for both the fields Title and ItemCat. So instead use keyword field in match query.
query: {
multi_match: {
query: query.suche,
fields: [ "Title.keyword^10", "ItemCat.keyword^5" ]
}
}
If you are not looking for exact match in Title then another way can be to set fields as below:
fields: [ "Title^10", "ItemCat.keyword^5" ]

Hello, I am trying to use wildcard query with filters in elastric search in my node js application

I am getting search item from user as
let eventSearch="*"+event.SearchTerm+"*";
This is the query object
let queryObject =
{
index: 'mark_deling_test2',
type: 'product',
body: {
"from" : event.StartIndex, "size" : event.ResultSize,
"query": {
"filtered":{
"query":{
"query_string":{
"fields": [ "Name^2.5", "Description", "keywords^1.75" ],
"query":eventSearch,
"analyze_wildcard":true
}
},
"filter":{
"term":{
"groups": "CA-IBO"
}
}
}
}
}
};
Then sending this query object for searching
This is not working. If I don't use the filter it works.
Please Help!
Get mark_deling_test2/_search
{
“query”: {
“bool”: {
“must”: {
“query_string”: {
“query”: “nut*“,
“fields”: [“Name”, “Description”, “keywords”]
}
},
“filter”: {
“term”: {
“groups”: “US-IBO”
}
}
}
}
}

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);
}

Multiple types in Elasticsearch Type Filter

I have a filtered query like this
query: {
filtered: {
query: {
bool: {
should: [{multi_match: {
query: #query,
fields: ['title', 'content']
}
},{fuzzy: {
content: {
value: #query,
min_similarity: '1d',
}
}}]
}
},
filter: {
and: [
type: {
value: #type
}]
}}}
That works fine if #type is a string, but does not work if #type is an array. How can I search for multiple types?
This worked, but I'm not happy with it:
filter: {
or: [
{ type: { value: 'blog'} },
{ type: { value: 'category'} },
{ type: { value: 'miscellaneous'} }
]
}
I'd love to accept a better answer
You can easily specify multiple types in your search request's URL, e.g. http://localhost:9200/twitter/tweet,user/_search, or with type in the header if using _msearch, as documented here.
These are then added as filters for you by Elasticsearch.
Also, you usually want to be using bool to combine filters, for reasons described in this article: all about elasticsearch filter bitsets
This worked for me:
Within the filter parameter, wrap multiple type queries as should clauses for a bool query
e.g
{
"query": {
"bool": {
"must": {
"term": { "foo": "bar" }
},
"filter": {
"bool": {
"should": [
{ "type": { "value": "myType" } },
{ "type": { "value": "myOtherType" } }
]
}
}
}
}
}
Suggested by dadoonet in the Elasticsearch github issue Support multiple types in Type Query

Resources