Prisma1: Query/filter for random items

Created on 23 Feb 2017  路  17Comments  路  Source: prisma/prisma1

Update: See this comment for the accepted proposal.


It would be awesome to be able to request N random items from a table:

persons(random: 10){ # get 10 random people
    name
    avatarImage
    id
    groups { name id slug }
  }

The corresponding JS/TS client code could look like this:

const persons = await prisma.persons({ random: 10 })
kinfeature

Most helpful comment

I agree with @marktani to make it like:

query {
  items(orderBy: RANDOM first: 100) {
    id
  }
}

Wordpress have random like: 'orderby' => 'rand', 'showposts' => 100 so it could be good fit

All 17 comments

Great suggestion! A few more questions:

  • What's your use case for this? Is a client-side randomization not suitable?
  • What do you mean when you say random? Uniformly distributed? Obviously this would be pseudo-random either way :slightly_smiling_face:

Is a client-side randomization not suitable?

why pull a of elements into client side when a SQL query will do it much faster? :)

What do you mean when you say random? Uniformly distributed? Obviously distribthis would be pseudo-random either way

As uniformly distributed as possible; having this done on 100 let alone 1000+ unique records will be increasingly more costly to a browser on a low-powered phone.

why pull a of elements into client side when a SQL query will do it much faster? :)

I agree. Just exploring possible use cases here! If we implement this, it should tie in with

  • orderBy
  • filter
  • first/last

Not sure about

  • before/after

I'd love to have this too, as there is in my current app. E.g if I have a collection of "thoughts of the day":

  • should be able to show a different thought every day
  • the thought should be random but not get repeated until all the other thoughts have been used
  • should be able to cluster/filter the thoughts according to some property (e.g an English speaking user should only see the ones in English)

the thought should be random but not get repeated until all the other thoughts have been used

This would be possible using the filter argument. I think this API would work great:

query nextThought($previousIds: [ID!]!) {
  allThoughts(filter: {
    id_not_in: $previousIds
    language: "en-US"
  }
  first: 1 
  random: UNIFORM
) {
    id
  }
}

Yes but then how is this previousIds list stored, and how is it cleared? That sounds like pushing the problem to the client, which would need to make one more roundtrip to get the list of previousIds from some storage. Maybe use the custom queries feature https://github.com/graphcool/feature-requests/issues/40. In any case, one call should be enough otherwise the benefit of GraphQL is a bit lost.

Or maybe instead of random I can live with some basic predefined formulae (just give all thoughts incrementally, 1-3-2-4-6-5-..., decrementally, etc....).

Or maybe instead of random I can live with some basic predefined formulae (just give all thoughts incrementally, 1-3-2-4-6-5-..., decrementally, etc....).

Ahh I see. There's a difference in a random distribution (duplicates are possible) and a random permutation (no duplicates). I think @matthiasak was also referring to permutations but I thought it's about a distribution.

Then I'd suggest this API:

query thoughtsPermutation {
  allThoughts(
    orderBy: RANDOM
    first: 100
  ) {
    id
  }
}

Hey @marktani In addition to this, it would be nice to just be able to order by edge data just like we can filter by edge data:

{
  items: allProducts(
  filter: {
    group: { verified: true }
  }
  , orderBy: {member: { id } }
){
    id
    name
    images { url }
    basePrice
    description
    existingWillSign: willsigns(filter: {person:{id:"${id}"}}){ id signingCost }
    group { id name logo { url } }
  }
}

I agree with @marktani to make it like:

query {
  items(orderBy: RANDOM first: 100) {
    id
  }
}

Wordpress have random like: 'orderby' => 'rand', 'showposts' => 100 so it could be good fit

Because currently its not possible to do random in one query, because you can't for example query first and last item combined, just items next to each other. Or its possible?

You can do this:

query randoms($first: Int!, $second: Int!) {
  first: items(first: 1 skip: $first) {
    id
  }

  second: items(first: 1 skip: $second) {
    id
  }
}

and choose first and second randomly.

Any news on it? :)

Not yet but seems like a very useful feature that shouldn't take too much time to implement. For the next few weeks the focus of our core development team is mostly on implementing the Postgres + MongoDB connectors but this should also be a great feature for someone to contribute!

So is this proposal final? I was thinking to try to implement it in near future maybe

I really like this API proposal. It would look like the following using the JS/TS client:

const persons = await prisma.persons({ orderBy: RANDOM, first: 100 })

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 10 days if no further activity occurs. Thank you for your contributions.

Any update on this? This would be very helpfull

const persons = await prisma.persons({ orderBy: RANDOM, first: 100 })
Was this page helpful?
0 / 5 - 0 ratings