Retrieving Data

Pinia ORM provides a handful of methods to retrieve inserted data. In this section, we'll walk through various ways to query the Pinia Store.

When querying the data from the store, in most cases, you want to query data inside the computed property. This way, when any data changes, the part of your application where you use those data gets updated reactively. It works as same as Pinia Getters.

    <li v-for="user in users" :key="">
      {{ }}
import { mapRepos } from 'pinia-orm'
import User from '@/models/User'
export default {
  computed: {
      userRepo: User
    users () {
      return this.userRepo.all()
NOTE: To retrieve records with its relationships, you must explicitly specify which relationships to fetch by with the query chain. For example, if you want to fetch users with posts, you must do userRepo.with('posts').get(). See Relationships page for more detail.

Retrieving Models

Once you have created the repository, you are ready to start retrieving data from the store. Think of each repository as a powerful query builder allowing you to fluently query the store associated with the repository model. For example:

// Get all users from the store.
const users = useRepo(User).all()
The difference with the get is that this method will not process any query chain. It'll always retrieve all models. So this useRepo(User).withAll.all() won't retrieve any relations. Use always get.

The all method will return all of the results in the model's store. Since each repository serves as a query builder, you may also add constraints to queries, and then use the get method to retrieve the results.

// Get all active users.
const users = useRepo(User).where('active', true).get()

Don't worry, we'll cover all of the available query methods in upcoming sections.

Note that the retrieved models are indeed the model instances. Not the plain object. For example, when you call useRepo(User).get(), you'll get a list of User model instances as a result.

Retrieving Single Models

In addition to retrieving all of the records for the given store, you may also retrieve single records using find or first. Instead of returning a collection of models, these methods return a single model instance.

// Retrieve a model by its primary key.
const user = useRepo(User).find(1)
// Retrieve the first model matching the query constraints.
const user = useRepo(User).where('active', true).first()

Retrieving models with composite keys

You can query a record that has composite primary keys by passing the key as a string like so:

// Retrieve a model by its primary key.
const user = useRepo(User).find('[1,2]')
// Retrieve the first model matching the query constraints.
const user = useRepo(User).whereId('[1,2]').first()

Where Clauses

You may use the where method to add where clauses to the query. The most basic call to where requires 2 arguments. The first argument is the name of the field. The second argument is the value to evaluate against the field.

For example, here is a query that verifies the value of the "votes" column is equal to 100:

const users = useRepo(User).where('votes', 100).get()

You may also define the second argument as a closure to perform advanced checks.

const users = useRepo(User).where('votes', (value) => {
  return value >= 100

Finally, the first argument can be a closure to perform more powerful querying.

const users = useRepo(User).where((user) => {
  return >= 100 &&

Or Statements

You may chain where constraints together as well as add "or" clauses to the query. The orWhere method accepts the same arguments as the where method.

const users = useRepo(User)
  .where('votes', 100)
  .orWhere('name', 'John Doe')

If you need to group an "or" condition within parentheses, you should simply use closure to do so.

const users = useRepo(User)
  .where('votes', 100)
  .orWhere((user) => {
    return user.votes > 50 && === 'Jane Doe'


The orderBy method allows you to sort the result of the query by a given field. The first argument to the orderBy method should be the field you wish to sort by, while the second argument controls the direction of the sort, and maybe either asc or desc. If there is no second argument, the direction is going to defaults to asc.

// Order users by name.
const users = useRepo(User).orderBy('name').get()
// You may also chain orderBy.
const users = useRepo(User)
  .orderBy('age', 'desc')

You may also pass a function as the first argument. The function will accept a record that is being sorted, and it should return value to be sorted by.

// Sort user name by its third character.
const users = useRepo(User).orderBy(user =>[2]).get()

You can also order many to many relations by their pivot data. To do that you need to use useSortBy helper right now.

const users = userRepo.with('roles').orderBy((user) => {
  user.roles = useSortBy(user.roles, [['pivot.level', 'asc']])


The groupBy method allows you to group your results by columns.

// Group users by name.
const users = useRepo(User).groupBy('name').get()
// You may also chain groupBy.
const users = useRepo(User)
// or pass them at once
const users = useRepo(User).groupBy('name', 'age').get()


The useCache method allows you to cache the results if your store requests are more frequent. The initial retrieve query will be a bit smaller but all next are very fast.

For caching a custom Weakref provider is used. That way garbage collection is included.

// Generate a cache with a auto generated key.
const users = useRepo(User).useCache().get()
// Generate a cache with a manual key (recommanded).
const users = useRepo(User).useCache('key').get()
// Generate a cache with a manual key and dynamic params (recommanded).
const users = useRepo(User).useCache('key', { id: idProperty }).get()

You can access the current cache instance with the cache method

// Get the repos cache instance
const cache = useRepo(User).cache()
// Getting the size of the current cache
// Checking if a specific key exist

As a default configuration the cache is shared between the repos. If you don't want it to be shared you can set it in the config.

// Setting the cache not to be shared for every repo
  cache: {
    shared: false,

Limit & Offset

To limit the number of results returned from the query, or to skip a given number of results in the query, you may use the limit and offset methods.

const user = useRepo(User).limit(30).offset(10).get()

Relationship Existence & Absence

When querying the record, you may wish to limit your results based on the existence of a relationship. For example, imagine you want to retrieve all blog posts that have at least one comment. To do so, you may pass the name of the relationship to the has methods.

// Retrieve all posts that have at least one comment.

You may also specify count as well.

// Retrieve all posts that have at least 2 comments.
useRepo(User).has('comments', 2).get()

Also, you may add an operator to customize your query even more. The supported operators are =, !=, >, >=, <, and <=.

// Retrieve all posts that have more than 2 comments.
useRepo(User).has('comments', '>', 2).get()
// Retrieve all posts that have less than or exactly 2 comments.
useRepo(User).has('comments', '<=', 2).get()

If you need even more power, you may use the whereHas method to put "where" conditions on your has queries. This method allows you to add customized constraints to a relationship constraint, such as checking the content of a comment.

// Retrieve all posts that have comment from user_id 1.
useRepo(Post).whereHas('comments', (query) => {
  query.where('user_id', 1)

To retrieve records depending on the absence of the relationship, use the doesntHave and whereDoesntHave methods. These methods will work the same as has and whereHas but with the opposite result.

// Retrieve all posts that doesn't have comments.
// Retrieve all posts that doesn't have comment with user_id of 1.
useRepo(Post).whereDoesntHave('comments', (query) => {
  query.where('user_id', 1)

You have also the corresponding or conditions orHas, orDoesntHave, orWhereHas and orWhereDoesntHave.