Directus Filtering multiple fields - filter

I'm trying to filter Directus CMS data set through URL parameters.
This is a sample data set. I can successfully filter data set by single parameter.
{
"data":[
{
"id": "1",
"status": "published",
"category": "Novel",
"section": "Kids"
},
{
"id": "2",
"status": "published",
"category": "Novel",
"section": "Adults"
}
]
}
/items/books?filter[category][_eq]=Novel
gives me exactly what I expected which is 1 & 2 data records.
But I need to filter both "category" & "section" fields
/items/books?filter[category][_eq]=Novel&filter[section][_eq]=Adults
For above I receive an empty data set.
Why is this getting failed ? Where do I need to fix? Appreciate your support in advance. Thanks!

Try the following query:
/items/books?filter={"_or":[{"category":{"_eq": "Novel"}},{"section":{"_eq":"Adults"}}]}
An expanded version of the filter:
"_or": [
{
"category": {
"_eq": "Novel"
}
},
{
"section": {
"_eq": "Adults"
}
}
]
Visit the official docs to read more about filtering rules and logical operators.

Related

How to cleanly batch queries together in Gremlin

I am writing a GraphQL resolver that retrieves all vertices by a particular edge using the following query (created returns label person):
software {
created {
name
}
}
Which would resolve to the following Gremlin Query for each software node found:
g.V().hasLabel('software').has('name', 'ripple').in('created')
This returns a result that includes all properties of the object:
{
"result": [
{
"#type": "d",
"#rid": "#24:0",
"#version": 6,
"#class": "person",
"in_knows": [
"#35:0"
],
"name": "josh",
"out_created": [
"#32:0",
"#33:0"
],
"age": 32,
"#fieldTypes": "in_knows=g,out_created=g"
}
],
"dbStats": {
...
}
}
I realize that this will fall foul on GraphQL's N+1 query so i'm trying to batch queries together using a Dataloader pattern. (i'm also hoping to do property selections, so i'm not asking the database to return too much info)
So i'm trying to craft a query like so:
g.V().union(
__.hasLabel('software').has('name', 'ripple').
project('parent', 'child').by('id').
by(__.in('created').fold()),
__.hasLabel('software').has('name', 'lop').
project('parent', 'child').by('id').
by(__.in('created').fold())
)
But this results in the following where the props are missing and it just includes the id of the vertices I want:
{
"result": [
{
"parent": "ripple",
"child": [
"#24:0"
]
},
{
"parent": "lop",
"child": [
"#22:0",
"#23:0",
"#24:0"
]
}
],
"dbStats": {
...
}
}
My Question is, how can I have the Gremlin query return all of the props for the found vertices and none of the other props? Should I even been doing batching this way?
For anyone else reading, the query I was trying to write wouldn't work because the TraversalSet created in the .by(_.in('created') can't be cast from a List to an ElementMap as the stream cardinality wouldn't be enforced. (You can only have one record per row, I think?)
My working query would be to duplicate the keys for each row and specify the props needed (the query below is ok for gremlin 3.3 as used in ODB, otherwise if you've got < gremlin 3.4 replace the last by step with be(elementMap('name', 'age')):
g.V().union(
__.hasLabel('software').has('name', 'ripple').
as('parent').
in('created').as('child').
select('parent', 'child').
by(values('name')).
by(properties('id', 'name', 'age').
group().by(__.key()).
by(__.value())),
__.hasLabel('software').has('name', 'lop').
as('parent').
in('created').as('child').
select('parent', 'child').
by(values('name')).
by(properties('id', 'name', 'age').
group().by(__.key()).
by(__.value()))
)
So that you get a result like this:
{"data": [
{
"parent": "ripple",
"child": {
"id": 5717,
"name": "josh",
"age": 32
}
},
{
"parent": "lop",
"child": {
"id": 5709,
"name": "peter",
"age": 35
}
},
{
"parent": "lop",
"child": {
"id": 5713,
"name": "marko",
"age": 29
}
},
{
"parent": "lop",
"child": {
"id": 5717,
"name": "josh",
"age": 32
}
}
]
}
Which would allow you to create a lookup where you concat all results for "lop" and "ripple" into arrays.

Strapi Graphql query with filtering/conditional rendering

In my Strapi project, i'm trying to write a Graphql query that filters posts by an array of tags.
The post has to belong to all tags of the given array.
E.g. the post below would not meet the condition if given array is [1,2,3] but would pass the condition if array is [3,5].
Any help would be much appreciated
Example Post:
{
"id": "1",
"title": "Lorem Iopsum",
"created_at": "2021-02-19T22:53:19.204Z",
"tags": [
{
"id": "3",
"tag": "Porte De Gentily"
},
{
"id": "5",
"tag": "Bridges"
},
{
"id": "6",
"tag": "Towers"
}
]
}
I was trying something like:
query {
posts( where: {tags: {id_contains: [3,1]}}) {
title
tags{id},
created_at
}
}
You can do it something like this
query($ids:[ID]) {
posts( where: {tags: {id:$ids}}) {
title
tags{id},
created_at
}
}
And pass your ids as a query variable:
{
"ids": [1,5]
}

graphQL filter array containing ALL

I am quite new to graphQL, and after searching the whole afternoon, i didn't found my answer to a relative quite simple problem.
I have two objects in my strapi backend :
"travels": [
{
"id": "1",
"title": "Bolivia: La Paz y Salar de Uyuni",
"travel_types": [
{
"name": "Culturales"
},
{
"name": "Aventura"
},
{
"name": "Ecoturismo"
}
]
},
{
"id": "2",
"title": "Europa clásica 2020",
"travel_types": [
{
"name": "Clasicas"
},
{
"name": "Culturales"
}
]
}
]
I am trying to get a filter where I search for travels containing ALL the user-selected travel_types.
I then wrote a query like that :
query($where: JSON){
travels (where:$where) {
id # Or _id if you are using MongoDB
title
travel_types {name}
}
And the parameter i try to input for testing :
{
"where":{
"travel_types.name_contains": ["Aventura"],
"travel_types.name_contains": ["Clasicas"]
}
}
This should return an empty array, because none of the travels have both Aventura and Clasicas travel-types.
But instead it returns the travel with id=2. It seems that only the second filter is taken.
I searched for a query which would be like Array.every() in javascript, but i wasn't able to find.
Does someone has an idea how to achieve this type of filtering ?
Thank you very much,

How to group by Graphql query result

I have a following GraphQL query
query {
Result: querydata {
name
code
description
}
}
that returns me the following data
{
"data": {
"Result": [
{
"name": "Class1",
"code": "ST1",
"description": "Value"
},
{
"name": "Class1",
"code": "ST2",
"description": "Value"
},
{
"name": "Class2",
"code": "FS1",
"description": "Value"
},
{
"name": "Class2",
"code": "FS2",
"description": "Value"
}
]
}
}
In this data, I have a name field that either be "Class1" or "Class2". I wan't to group this data in a way that I can have Class1 and Class2 data separated. Is there any way of doing this. I could have achieved this by running 2 separate queries by providing a name filter but lets say I don't have that option.
I want to transform the result as follow
{
"data": {
"Result": [
"Class1": [
{
"code": "ST1",
"description": "Value"
},
{
"code": "ST2",
"description": "Value"
}
]
"Class2": [
{
"code": "FS1",
"description": "Value"
},
{
"code": "FS2",
"description": "Value"
}
]
]
}
}
What you are describing is something that should either happen on the client side or allow your query type to receive a name option that you use to return the propper class, then the query below would work for what you are needing assuming it was able to lookup the name of the querydata
query {
Class1: querydata(name: "Class1") {
code
description
}
Class2: querydata(name: "Class2") {
code
description
}
}

Filter where attribute is in supplied array

Suppose I have these documents in a Things table:
{
"name": "Cali",
"state": "CA"
},
{
"name": "Vega",
"state": "NV",
},
{
"name": "Wash",
"state": "WA"
}
My UI is a state-picker where the user can select multiple states. I want to display the appropriate results. The SQL equivalent would be:
SELECT * FROM Things WHERE state IN ('CA', 'WA')
I have tried:
r.db('test').table('Things').filter(r.expr(['CA', 'WA']).contains(r('state')))
but that doesn't return anything and I don't understand why that wouldn't have worked.
This works for getting a single state:
r.db('test').table('Things').filter(r.row('state').eq('CA'))
r.db('test').table('Things').filter(r.expr(['CA', 'WA']).contains(r.row('state')))
seems to be working in some versions and returns
[
{
"id": "b20cdcab-35ab-464b-b10b-b2f644df73e6" ,
"name": "Cali" ,
"state": "CA"
} ,
{
"id": "506a4d1f-3752-409a-8a93-83385eb0a81b" ,
"name": "Wash" ,
"state": "WA"
}
]
Anyway, you can use a function instead of r.row:
r.db('test').table('Things').filter(function(row) {
return r.expr(['CA', 'WA']).contains(row('state'))
})

Resources