is there a possibility to filter items if a edge of this item does not have a property / edge?
example:
I have two likes, both likes have an edge (likedFeedback) that can have a toPerson.
This query
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) {
dgraph.type
likedFeedback
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
will give me
{
"likes": [
{
"dgraph.type": [
"ActivityGraphModel",
"LikeFeedbackGraphModel"
],
"likedFeedback": {
"uid": "0x396ba8",
"fromPerson": {
"uid": "0x396ba6"
}
}
},
{
"dgraph.type": [
"ActivityGraphModel",
"LikeFeedbackGraphModel"
],
"likedFeedback": {
"uid": "0x396ba9",
"fromPerson": {
"uid": "0x396ba6"
},
"toPerson": {
"uid": "0x396ba7"
}
}
}
]
}
Now, I would like to filter out the likes that references a likedFeedback with a toPerson, something like:
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) @filter(has(likedFeedback.toPerson)) {
dgraph.type
likedFeedback
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
Is that even possible? I tried with @cascade but I couldn’t make it work. can I get some hints?
1 Like
MichelDiz
(Michel Diz)
January 22, 2022, 6:57pm
2
Not sure if I get it, but try something like this
query getAll(){
var(func: type(LikeFeedbackGraphModel))
@filter(has(likedFeedback)) @cascade {
LK as uid
likedFeedback {
toPerson { uid }
}
}
likes(func: uid(LK)){
dgraph.type
likedFeedback {
uid
fromPerson { uid }
toPerson { uid }
}
}
}
1 Like
No, unfortunately this does not work.
The edge toPerson inside likedFeedback is optional. I want to get rid of the likes to feedbacks with a optional toPerson.
So, of the example json above, where we have 2 likes, I would like to see only
{
"dgraph.type": [
"ActivityGraphModel",
"LikeFeedbackGraphModel"
],
"likedFeedback": {
"uid": "0x396ba9",
"fromPerson": {
"uid": "0x396ba6"
},
"toPerson": {
"uid": "0x396ba7"
}
}
}
and filter out the other one where toPerson is optional.
1 Like
MichelDiz
(Michel Diz)
January 23, 2022, 4:24pm
4
Sorry, but I’m really confused with what you want.
All of them?
This JSON says nothing to me.
How can you tell when it is optional or not?
No problem, I’m thankful you are there to help me!
MichelDiz:
All of them?
So, with “Optional” I mean that some node have the edge “toPerson” and some does not have it.
Ok, I try to explain that sample data.
It’s an array of 2 items of LikeFeedbackGraphModel.
Both of them have a “likedFeedback” edge.
The first “likedFeedback” HAS a toPerson, but the second does not have it, because it’s optional to have it.
It is more clear now?
I would use the has filter, like so
@filter(has(toPerson))
but I want to filter the first level node (the LikeFeedbackGraphModel), not the likedFeedback.
so instead of doing
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) {
dgraph.type
likedFeedback @filter(has(toPerson))
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
I would like to do
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) @filter(has(likedFeedback.toPerson)) {
dgraph.type
likedFeedback
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
because I want to filter the first level, and not the likedFeedback edge. I tried using cascade but it didn’t work.
MichelDiz
(Michel Diz)
January 23, 2022, 5:52pm
6
That’s really not possible due to DQL’s syntax, Cuz predicates can have dots. If we support this level of filtering the syntax will be different. Something like @filter(has((likedFeedback).toPerson))
or something else.
It is not possible to filter like this in DQL right now. The only way is by doing cascade tho.
The way you are explaining confuses me. Cuz first looks like you don’t wanna the nodes with toPerson and then you say in a way that you want it. Based on your responses I was about to suggest something like
likedFeedback @filter(NOT has(toPerson))
PS. Have you tried this?
likedFeedback @filter(has(toPerson) and has(fromPerson) )
MichelDiz:
The way you are explaining confuses me. Cuz first looks like you don’t wanna the nodes with toPerson and then you say in a way that you want it. Based on your responses I was about to suggest something like
likedFeedback @filter(NOT has(toPerson))
Yeah, you’re right, I’m dumb. I meant exactly this.
Now, this query works fine.
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) {
dgraph.type
uid
likedFeedback @filter(NOT has(toPerson))
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
and as you see I get
"likes": [
{
"dgraph.type": [
"ActivityGraphModel",
"LikeFeedbackGraphModel"
],
"uid": "0x39b8bf",
"likedFeedback": {
"uid": "0x39b8bd",
"fromPerson": {
"uid": "0x39b8bb"
}
}
},
{
"dgraph.type": [
"ActivityGraphModel",
"LikeFeedbackGraphModel"
],
"uid": "0x39b8c0"
}
]
The problem is that I still get the second like, which I want to exclude.
I should fix that by adding @cascade
query getAll(){
likes (func: type(LikeFeedbackGraphModel)) @cascade {
dgraph.type
uid
likedFeedback @filter(NOT has(toPerson))
{
uid
fromPerson { uid }
toPerson { uid }
}
}
}
but instead, by doing this I’ll get 0 likes, empty array.
Maybe I understood wrongly how @cascade should work?
MichelDiz
(Michel Diz)
January 23, 2022, 9:19pm
8
Cascade will remove from the result all of those who hasn’t all given predicates in the body of the query. Which means, in your query you are asking for both fromPerson and toPerson. So it will fall cuz you also have a NOT filter toPerson. Remove the toPerson from the body and you should be good to go.
Not ideal, but I can live with with @cascade for now.
Are filter predicate gonna support nested property in the future?
MichelDiz
(Michel Diz)
January 24, 2022, 4:28pm
10
No plans for now. But there are open tickets about this.