Skip to content
This repository was archived by the owner on Sep 2, 2022. It is now read-only.

Query/filter for random items #114

Closed
matthiasak opened this issue Feb 23, 2017 · 17 comments
Closed

Query/filter for random items #114

matthiasak opened this issue Feb 23, 2017 · 17 comments

Comments

@matthiasak
Copy link

matthiasak commented Feb 23, 2017

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 })
@marktani
Copy link
Contributor

marktani commented Feb 23, 2017

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 🙂

@matthiasak
Copy link
Author

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.

@marktani
Copy link
Contributor

marktani commented Feb 25, 2017

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

@sedubois
Copy link

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)

@marktani
Copy link
Contributor

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
  }
}

@sedubois
Copy link

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....).

@marktani
Copy link
Contributor

marktani commented Mar 10, 2017

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
  }
}

@matthiasak
Copy link
Author

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 } }
  }
}

@huv1k
Copy link
Contributor

huv1k commented Feb 9, 2018

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

@huv1k
Copy link
Contributor

huv1k commented Feb 23, 2018

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?

@marktani
Copy link
Contributor

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.

@huv1k
Copy link
Contributor

huv1k commented Mar 26, 2018

Any news on it? :)

@schickling
Copy link
Member

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!

@huv1k
Copy link
Contributor

huv1k commented Sep 19, 2018

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

@schickling
Copy link
Member

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 })

@stale
Copy link

stale bot commented Jan 8, 2019

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.

@stale stale bot added the status/stale Marked as state by the GitHub stalebot label Jan 8, 2019
@do4gr do4gr removed the status/stale Marked as state by the GitHub stalebot label Jan 8, 2019
@adrianescat
Copy link

Any update on this? This would be very helpfull

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

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

10 participants