js-data

Respect Your Data

Give your data the treatment it deserves with a framework-agnostic, datastore-agnostic JavaScript ORM built for ease of use and peace of mind. Works in Node.js and in the Browser.

Get Started

Query Syntax

Collection#filter and DataStore#filter allow for selecting subsets of records out of an in-memory collection. The filter method understands a query syntax that will allow you to filter, sort, offset & limit data. If your server or persistence layer can be taught to understand the same syntax, then you should be able to pass the same parameters to findAll and then to filter and get the same data. All of the JSData Adapters except the Http adapter understand this query syntax. If you're using the Http adapter in the browser but not using JSData on the server, then it's up to you to help JSData understand how your server returns data. If you don't want to mess with your server code, then you can override the operators in the Query class with implementations that follow your own query syntax.

Filtering (WHERE)

Filtering selects a subset of data according to some criteria. This is like your WHERE clause in SQL. See all operators of the Query class..

Operators

All operators work like this: match all items where item[field] operator criteriaValue is true. By default, all clauses are ANDed together. You can turn a particular clause into an OR by prefixing the operator with a pipe (|).

Apply multiple filters to the same field

// Get all users where age is between 30 and 33
const users = store.filter('user', {
  where: {
    'age': {
      '>=': 30,
      '<=': 33
    }
  }
})
==

Uses JavaScript's == operator to check for equality.

// Get all comments where comment.userId == 5
const comments = store.filter('comment', {
  where: {
    userId: {
      '==': 5
    }
  }
})

Shorthand for the == operator:

// Get all comments where comment.userId == 5
const comments = store.filter('comment', {
  userId: 5
})
!=

Uses JavaScript's != operator to check for inequality.

// Get all comments where comment.userId != 5
const comments = store.filter('comment', {
  where: {
    userId: {
      '!=': 5
    }
  }
})
>

Uses JavaScript's > operator.

// Get all users where user.age > 30
const users = store.filter('user', {
  where: {
    age: {
      '>': 30
    }
  }
})
>=

Uses JavaScript's >= operator.

// Get all users where user.age >= 30
const users = store.filter('user', {
  where: {
    age: {
      '>=': 30
    }
  }
})
<

Uses JavaScript's < operator.

// Get all users where user.age < 30
const users = store.filter('user', {
  where: {
    age: {
      '<': 30
    }
  }
})
<=

Uses JavaScript's <= operator.

// Get all users where user.age <= 30
const users = store.filter('user', {
  where: {
    age: {
      '<=': 30
    }
  }
})
isectEmpty

Looks for items where item[field] does not intersect the given array.

// Get all posts where post.tags does not intersect ['baseball', 'football']
const posts = store.filter('post', {
  where: {
    tags: {
      'isectEmpty': ['baseball', 'football']
    }
  }
})
isectNotEmpty

Looks for items where item[field] intersects the given array.

// Get all posts where post.tags intersects ['baseball', 'football']
const posts = store.filter('post', {
  where: {
    tags: {
      'isectNotEmpty': ['baseball', 'football']
    }
  }
})
in

Looks for items where item[field] is in the given term, which can be a string or an array.

// Get all users where user.name is in "John Anderson"
const users = store.filter('user', {
  where: {
    name: {
      'in': 'John Anderson'
    }
  }
})

// Get all users where user.role is in ["admin", "owner"]
const users = store.filter('user', {
  where: {
    role: {
      'in': ['admin', 'owner']
    }
  }
})
notIn

Looks for items where item[field] is not in the given term, which can be a string or an array.

// Get all users where user.name is NOT in "John Anderson"
const users = store.filter('user', {
  where: {
    name: {
      'notIn': 'John Anderson'
    }
  }
})

// Get all users where user.role is NOT in ["admin", "owner"]
const users = store.filter('user', {
  where: {
    role: {
      'notIn': ['admin', 'owner']
    }
  }
})
contains

Looks for items where item[field] (which can be a string or an array) contains the given term.

// Get all users where user.name contains "John"
const users = store.filter('user', {
  where: {
    name: {
      'contains': 'John'
    }
  }
})

// Get all users where user.roles contains "admin"
const users = store.filter('user', {
  where: {
    roles: {
      'contains': 'admin'
    }
  }
})
notContains

Looks for items where item[field] (which can be a string or an array) does not contain the given term.

// Get all users where user.name does NOT contain "John"
const users = store.filter('user', {
  where: {
    name: {
      'notContains': 'John'
    }
  }
})

// Get all users where user.roles does NOT contain "admin"
const users = store.filter('user', {
  where: {
    roles: {
      'notContains': 'admin'
    }
  }
})
like

Looks for items where item[field] (a string) matches a wildcard search term.

You can append RegExp modifiers to the operator (i, U, etc).

// Get all users where user.name matches "john" in any letter case combination.
const users = store.filter('user', {
  where: {
    name: {
      'likei': 'john'
    }
  }
})

// Get all users where user.name contains "john" and "doe" anywhere in the name.
const users = store.filter('user', {
  where: {
    name: {
      'like': '%john%doe%'
    }
  }
})

Sorting (sort/orderBy)

Sorting orders the filtered data by a particular field or fields. This is like your ORDER BY clause in SQL.

// Sorts users by age in ascending order
const users = store.filter('user', {
  orderBy: 'age'
})

// Sorts users by age and then name in ascending order
const users = store.filter('user', {
  orderBy: ['age', 'name']
})

// Sorts users by age in descending order
const users = store.filter('user', {
  orderBy: [
    ['age', 'DESC']
  ]
})

// Sorts users by age in descending order and then sort by name in ascending order to break a tie
const users = store.filter('user', {
  orderBy: [
    ['age', 'DESC'],
    ['name', 'ASC']
  ]
})

Paging (offset/skip & limit)

Paging involves skipping and limiting data filtered and sorted data. This is like your OFFSET and LIMIT clauses in SQL.

const PAGE_SIZE = 20
let currentPage = 1

// Grab the first "page" of posts
const posts = store.filter('post', {
  offset: PAGE_SIZE * (currentPage - 1),
  limit: PAGE_SIZE
})