-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support of Value Variables for uid_in. #3066
Comments
This query could also be written cascade and normalize {
caro(func: eq(name@en, "Marc Caro"))
@cascade @normalize {
director.film {
film: name@en
~director.film @filter(eq(name@en, "Jean-Pierre Jeunet")) {
name@en
}
}
}
} If enough people request this we could consider it, but for now I think we can just keep it for later. |
Adding just one more example (sample in the end):In my dataset, I would like to return only those friends who have (or Not in some cases) the same party in common "with me" (Who is the point/target of the query).
The straight forward query would be like this below - However, I need to already know the uid from my party that I'm a member of. That's not ideal. Not all users will deal with UIDs directly in their end applications. {
q(func: eq(name, "Jane Doe")) {
uid
name
memberOf {
uid
Party
}
friend @filter(NOT uid_in(memberOf, 0xa1257)) { #this case is "not part of some know party"
uid
name
}
}
} To resolve this query along with the current procedures, we would need to create one more block var to take my (Jane Doe) party and then keep "memberOf" as reverse. Then it would be possible to take all (which could be numerous) users who are in the same party (or equivalent) and use their UIDs to filter on the final query.
{
Jane as var (func: eq(name, "Jane Doe")) {
uid
memberOf {
Party
~memberOf {
uid
Fellas as name
}
}
}
q(func: uid(Jane)) {
uid
name
memberOf {
uid
Party
}
friend @filter(NOT uid(Fellas)) {
uid
name
}
}
} Using var and Val we can solve this {
q(func: eq(name, "Jane Doe")) {
uid
name
memberOf {
myparty as uid #Extracting the party to user in the uid_in func
Party
}
friend @filter(NOT uid_in(memberOf, val(myparty))) { # Easily applying a filter without multiple round trips
uid
name
}
}
} The result: {
"data": {
"q": [
{
"uid": "0xa1255",
"name": "Jane Doe",
"memberOf": [
{
"uid": "0xa1257",
"Party": "Republican Party"
}
],
"friend": [
{
"uid": "0xa1256",
"name": "Lucas Lee"
},
{
"uid": "0xa125d",
"name": "Julia Doe"
}
]
}
]
}
} {
"set": [{
"uid": "_:Jane",
"address": {
"addressLocality": "Colorado Springs",
"addressRegion": "CO",
"postalCode": "80840",
"streetAddress": "100 Main Street"
},
"colleague": {
"uid": "_:JohnColleague",
"name": "JohnColleague"
},
"email": "[email protected]",
"image": "janedoe.jpg",
"jobTitle": "Research Assistant",
"name": "Jane Doe",
"alumniOf": "Dartmouth",
"birthPlace": "Philadelphia, PA",
"birthDate": "1979-10-12",
"height": "72 inches",
"gender": "female",
"friend": [{
"uid": "_:Lucas"
},
{
"uid": "_:Julia"
},
{
"uid": "_:Jin"
}
],
"memberOf": {
"uid": "_:Republican",
"Party": "Republican Party"
},
"nationality": "Albanian",
"telephone": "(123) 456-6789",
"url": "http://www.example.com"
},
{
"uid": "_:Jin",
"address": {
"addressLocality": "Colorado Springs",
"addressRegion": "CO",
"postalCode": "80840",
"streetAddress": "100 Main Street"
},
"colleague": {
"uid": "_:JameColleague",
"name": "JameColleague"
},
"email": "[email protected]",
"image": "Jin.jpg",
"jobTitle": "Research Assistant",
"name": "Jin Ang",
"alumniOf": "Dartmouth",
"birthPlace": "Hangzhou, Zhejiang",
"birthDate": "1978-10-12",
"height": "72 inches",
"gender": "male",
"friend": [{
"uid": "_:Lucas"
},
{
"uid": "_:Julia"
},
{
"uid": "_:Jane"
}
],
"memberOf": {
"uid": "_:Republican",
"Party": "Republican Party"
},
"nationality": "Chinese",
"telephone": "(555) 555-55555",
"url": "http://www.example.com"
},
{
"uid": "_:Lucas",
"address": {
"addressLocality": "Colorado Springs",
"addressRegion": "CO",
"postalCode": "80840",
"streetAddress": "100 Main Street"
},
"colleague": {
"uid": "_:JameColleague",
"name": "JameColleague"
},
"email": "[email protected]",
"image": "Lucas.jpg",
"jobTitle": "Research Assistant",
"name": "Lucas Lee",
"alumniOf": "Dartmouth",
"birthPlace": "San Francisco, CA",
"birthDate": "1982-11-01",
"height": "72 inches",
"gender": "male",
"friend": [{
"uid": "_:Jin"
},
{
"uid": "_:Julia"
},
{
"uid": "_:Jane"
}
],
"memberOf": {
"uid": "_:Democrats",
"Party": "Democrats"
},
"nationality": "Noth American",
"telephone": "(123) 456-6789",
"url": "http://www.example.com"
},
{
"uid": "_:Julia",
"address": {
"addressLocality": "San Diego",
"addressRegion": "CA",
"postalCode": "92111",
"streetAddress": "Argyle St"
},
"colleague": {
"uid": "_:JameColleague",
"name": "JameColleague"
},
"email": "[email protected]",
"image": "Julia.jpg",
"jobTitle": "Research Assistant",
"name": "Julia Doe",
"alumniOf": "Dartmouth",
"birthPlace": "Philadelphia, PA",
"birthDate": "1979-10-12",
"height": "72 inches",
"gender": "female",
"friend": [{
"uid": "_:Jin"
},
{
"uid": "_:Lucas"
},
{
"uid": "_:Jane"
}
],
"memberOf": {
"uid": "_:Democrats",
"Party": "Democrats"
},
"nationality": "Albanian",
"telephone": "(123) 456-6789",
"url": "http://www.example.com"
}
]
} |
We could also do this with 2 var blocks + 1 query block: {
Jane as var(func: eq(name, "Jane Doe")) {
myparty as memberOf
}
var(func: uid(Jane)) {
friend {
memberOf @filter(uid(myparty)) {
Fellas as ~memberOf
}
}
}
q(func: uid(Jane)) {
uid
name
memberOf {
uid
Party
}
friend @filter(NOT uid(Fellas)) {
uid
name
}
}
} BTW - There is another important point to mention.As far as I know, it would not be possible to get a value via Val in the same block ( {
Jane as var(func: eq(name, "Jane Doe")) {
myparty as memberOf #Extracting the party to user in the uid_in func
}
q(func: uid(Jane)) {
uid
name
memberOf {
uid
Party
}
friend @filter(NOT uid_in(memberOf, val(myparty))) { # Easily applying a filter without multiple round trips
uid
name
}
}
} And another important fact to point out. Is that this query above would only be safe in the context of a direct query where returns only one entity. However, if the query has multiple entities (like "show me all users and apply this rule") this approach would not be safe. It would capture all parties of all people and they would all be filtered out. Returning null for the edge friend. |
I've noticed that the value variable works fine in uid_in if I convert the UID to number using a hexadecimal converter (Which cannot be done on the fly in the query). The issue is related to the lack of the possibility of conversion of UID to string. That is, it would be necessary for Value Variable to convert the UID to number and/or string. {
var(func: uid(0x0)){
a as math(637870)
}
caro(func: eq(name@en, "Marc Caro")) {
uid
name@en
director.film @filter(uid_in(~director.film, val(a)) ) {
name@en
}
}
} {
"data": {
"caro": [
{
"uid": "0x108cd1",
"name@en": "Marc Caro",
"director.film": [
{
"name@en": "The City of Lost Children"
},
{
"name@en": "Delicatessen"
},
{
"name@en": "The Bunker of the Last Gunshots"
},
{
"name@en": "L'évasion"
}
]
}
]
}
} |
I have encountered a similar problem.
How do I filter out friends of a person who do not live in a country?
Even with the way mentioned in your reply in Oct 1, it still does not support a list of uid. |
Really struggling without this feature since I can't use cascade to do filtering (some of my predicates are nullable, and if I use cascade, it excludes all the nodes containing predicates with nulls in the response). This is especially painful when trying to do a conditional upsert where I want to set fields only if they are null. My data model looks like this. I have Hosts and VMs- but VMs can move between hosts throughout time, so I also have a vm_info node that sits between hosts and vms that tracks start/end time. Ex. Host1 had VM1 running on it from M-F, but VM2 running on it T-W and F-S. That means I'll have 3 vm_info nodes attached to the Host1 node. Since the graph is updated in realtime, the If I want to get the vm_info nodes that have an edge to Host1 and an edge to VM2, I can't do this right now without overfetching (potentially a lot).
|
The error message has changed since the issue was reported. It now throws
|
As a side note the below query works because
Tagging @ashish-goswami @pawanrawal and @MichelDiz. |
@seanlaff Can you give me the query which you are running to by-pass the issue right now? Also can you give me a version of query which you want to run to avoid pulling unnecessary data? I am wondering if we could have a better way to solve your problem with the existing supported variables/functions. |
@anurags92 I ended up solving it like this
Followed by a bunch of conditional mutations, i.e I think the most painful part is that I cannot easily batch these kind of requests. |
This PR looks interesting, in regards to my cascade filtering issue #5607 |
@anurags92 Awesome! |
Experience Report
What you wanted to do
This could avoid problems with UID changes in Nodes. And be used in documentation.
Why that wasn't great, with examples
Most functions accept Query Variables
BTW
uid_in works fine with DQL Variables.
Some discussion on this https://discuss.dgraph.io/t/uid-in-cant-use-variables/2772
https://discuss.dgraph.io/t/improve-uid-in-with-value-variable/5266
The text was updated successfully, but these errors were encountered: