graphql icon indicating copy to clipboard operation
graphql copied to clipboard

Return score for fulltext index search

Open darrellwarde opened this issue 2 years ago • 4 comments

It would be good if users could access the score for fulltext index search results. However, this will not nicely fit into the current API, as it would just need to be added to the node type, which is a hacky fix.

We could potentially get around this by using a return payload as we do with Mutations. For instance, for a type Movie:

type Movie @fulltext(indexes: [{ name: "MovieTitle", fields: ["title"] }]) {
  title: String!
}

type QueryInfo {
  fulltextScore: Float
}

type MoviesQueryResponse {
  info: QueryInfo!
  movies: [Movie!]!
}

type Query {
  movies(fulltext: MovieFulltext, where: MovieWhere, options: MovieOptions): MoviesQueryResponse!
}

darrellwarde avatar May 09 '22 11:05 darrellwarde

This might seem a tad unorthodox, but you could think of a search as a "connection" and then the full text score becomes an edge property.

We already have top-level-connections, so you could just inject the score as an edge property before returning the connection.

litewarp avatar May 09 '22 13:05 litewarp

And I just realise that my suggestion above was not all that great, as the fulltext score needs to be associated with each individual result and not the entire response! We could perhaps consider a root-level Query field specifically for fulltext index searches...

darrellwarde avatar May 09 '22 13:05 darrellwarde

@darrellwarde Did you see my suggestion above ☝🏾

We could implement it like:


type Movie @fulltext(indexes: [{ name: "MovieTitle", fields: ["title"] }]) {
  title: String!
} 

type MovieEdge {
  // <-- fulltext only gets added to edge if @fulltext directive used
  fulltextScore: Float
  cursor: String!
  node: Movie!
}

type MoviesConnection {
  totalCount: Int!
  edges: [MovieEdge!]!
  pageInfo: PageInfo!
}

type Query {
  moviesConnection(
    first: Int, 
    after: String, 
    where: MovieWhere, 
    sort: [MovieSort!]!, 
    // <-- fulltext argument only gets added to query if @fulltext directive used
    fulltext: MovieFulltext
  ): MoviesConnection! 
}

You'll need a runtime check to make sure that if fulltext is in the selection set, fulltext has been provided as an argument.

If fulltext is properly in the selectionset, you alter the cypher to run the fulltext query, and then move the score field into the edge and return the node like normal.

I don't believe this approach would be breaking in any way.

litewarp avatar May 09 '22 13:05 litewarp

Hey @litewarp, apologies, I think I glossed over your suggestion!

This is a super interesting idea, and I feel an appropriate use of the edge field!

darrellwarde avatar May 10 '22 12:05 darrellwarde