How do I query on any of the attributes on nodes

If I have a types like

type Student {
name
dob
home_address
studentatt1
studentatt2
studentatt_n
}

type Worker {
name
dob
work_address
workeratt1
workeratt2
workeratt_n
}

and want to find all nodes in DQL where one of the attributes contains the value “bob”. Is there a simple way, or do I have to build a @filter with or all the attributes?

Thanks in advance

Lasse

1 Like
{
  q(func: type(Student)) @filter(eq(name, "Bob")) {
    name
    dob
    home_address
    ...
  }
}

OR

{
  q(func: eq(name, "Bob")) {
    name
    dob
    home_address
    ...
  }
}

OR

{
  q(func: has(name)) @filter(eq(name, "Bob")) {
    name
    dob
    home_address
    ...
  }
}

I believe what he is looking for is a function to look in all predicates not just the name predicate… and there is not a easy to do that other then building a query with multiple OR statements searching each predicate specifically by name.

I think a good reference for the intention would be:

This matches the instances of any attribute type whose value matches the given regex - “Miriam Morton” or “Solomon Tran”.

But this is only possible because typeDB only stores singular instances of string values and not triples like Dgraph stores its data.

amster507 you are right.

I want to return any type, matching one of attributes on that type.
For now I have implemented a solution where I create a huge or statement based on the type definitions.
I works fine, but I’m a little bit concerned about performances, but I can see the engine complains if no index or the wrong index exists, so perhaps it us all the underlying indexes.

impressive, you got it with so little context lol

Performance for this will always be an issue as Dgraph is not designed for performance for this use case. Performance will degradate even more if you try it with a more complex function on many predicates such as regex matching.

@MichelDiz probably, because I have been down this same road already lol.

1 Like

@Lasse_Nedergaard

I agree with @amaster507’s point regarding performance. Searching every string in a very large graph would be very inefficient.

I’ve solved this problem (partially?) in the past using custom types and interfaces in GraphQL SDL.

Consider this schema:

interface INode {
    id: ID!
}

type SearchableString {
    value: String! @search(by: [hash, term, fulltext, regexp])
    owner: INode 
}

type Student implements INode {
    firstName: SearchableString
    lastName: SearchableString

    address: String
}

type Teacher implements INode {
    fullName: SearchableString

    officeAddress: String
}

This defines a “SearchableString” string type that also contains an edge back to its “owner”. Here I’m saying I want to be able to search nodes containing this searchable type.

A query might look like this:

query QuerySearchableString($filter: SearchableStringFilter) {
  querySearchableString(filter: $filter) {
    owner {
      __typename
      ... on Student {
        id
        firstName {
          value
        }
        lastName {
          value
        }
        address
      }
      ... on Teacher {
        id
        fullName {
          value
        }
        officeAddress
      }
    }
  }
}

variables:

{
  "filter": {
    "value": {
      "allofterms": "bob"
    },
    "or": [
      {
        "value": {
          "regexp": "/[Bb]ob/"
        }
      }
    ]
  }
}

This gives you the ability to search for “Bob” across any node that happens to have the SearchableString type(s) as an edge. Definitely not as good as “find ‘bob’ in any text in the graph”, but definitely a ton more efficient.

I’ve pushed this all up to my sandbox if you want to have a closer look: https://github.com/matthewmcneely/dgraph-v21.03-sandbox/tree/explanations/custom-type-for-string-queries

1 Like

Thanks for the idea.
In our case we have defined a shared interface for all the attributes shared (name,
dob) between all types (Student and Worker) and for all the type specific attributes created uniqe indexes and here we could change them to searchableString and thereby have a fixed number indexes to search and of cause the same can be done on our shared interface.
I will have to create some large scale tests to get an idea what is the best implementation as your suggestion also complicate the graph.

Lasse