Search priority using dgraph


#1

Hi,
I have a general question regarding search using dgraph. I wish to search on a text as regular expression but want to have the exact matches ranked higher. Is there a way to do this? I am trying to use the following but the “cond” code throws an error.

Thanks

query test($nam: string = "sty")
{
  q1 as var (func:eq(dgraph.type,Xtype)) @filter(regexp(name,/$nam/)) {
    myn as name
    vx as math(cond(myn==$nam,1,2))
  }
  q2 (func:uid(q1),orderasc:val(vx)){
    name
  }
}

(Michel Conrado) #2

What version are you using?
Why are you using eq(dgraph.type,Xtype) ?

cond operator needs a true/false at 0 position, and will return 1 or 2 values if the first value is true or false. Not sure what you trying to do with this operator.

Ranked by what? if you order by ,orderasc:name@en you gonna have the exact matches first.


#3

Thanks for getting back on this.

“Ranked by what? if you order by ,orderasc:name@en you gonna have the exact matches first.”

This is not true. Suppose I do a regexp for /sty/ on name, I would get the following order:

aasty
sty
style

While I would like the following order:

sty
aasty
style

I am using the following version:
v1.0.14-rc2

eq(dgraph.type,Xtype) is root search – can be replaced by any other search to narrow down the elements I want to perform search on.

With cond operator, I wanted to rank the exact match higher and I could then use:
orderasc:val(vx), orderasc:name

Is there a way I can create such a variable? Or any other way I can achieve the intended sort which gives the exact match first followed by other matches.

I could do 2 queries (first for exact and then for regexp) but it’ll be difficult to paginate across those 2 queries. Wanted to see if there is an elegant way.


(Michel Conrado) #4

oh, you’re right. But without sorting, is the result radom? and isn’t like you wish?

The thing is “dgraph.type” will be used to define Types in the new type system. This can be problematic if you upgrade to latest releases. Just keep an eye on it.

https://docs.dgraph.io/master/query-language/#type-system

Maybe, if you add an extra edge recording the total of letters in the “name@.”. That way you could use that edge to “rank” the words.

So your query would look like:

query test($nam: string = "sty")
{
  q1 as var (func:eq(dgraph.type,Xtype)) @filter(regexp(name,/$nam/)) {
    myn as name
    RK as rankedValue
  }
  q2 (func:uid(q1), orderasc:val(RK), orderasc:name@en){
    name
  }
}