0.2.0 • Published 5 years ago

@geekfiftyfive/objectquery v0.2.0

Weekly downloads
15
License
Apache-2.0
Repository
github
Last release
5 years ago

alt text alt text alt text

Introduction

ObjectQuery is a library to run queries against arrays of JavaScript objects, with the queries themselves being written as JavaScript objects. The aim of this is to make the syntax fairly intuitive, with as close to a 1:1 mapping with the structure of the original objects as possible.

Installing and Running

Install the project by running the following:

npm install @geekfiftyfive/objectquery

You can then filter arrays of Objects as follows:

const ObjectQuery = require("@geekfiftyfive/objectquery");

let output = ObjectQuery.filter({ /* query object */ }, [ /* array of objects to filter */ ]);

Syntax

1. Equality

Checking for equality is fairly intuitive. Say I have the following array of objects:

[
  {
    "project": "Awesome Project",
    "version:": "1.0.0",
    "language": "JavaScript",
    "dependencies": 3
  },
  {
    "project": "Superb Library",
    "version": "0.5.0",
    "language": "Java",
    "dependencies": 5
  },
  {
    "project": "Hello World",
    "version": "0.0.1",
    "language": "JavaScript",
    "dependencies": 1
  }
]

If I wanted to filter by projects with the language field being equal to JavaScript, then I would simply use the following object for my query:

{
  "language": "JavaScript"
}

running ObjectQuery.filter as shown above would then yield the following array:

[
  {
    "project": "Awesome Project",
    "version:": "1.0.0",
    "language": "JavaScript",
    "dependencies": 3
  },
  {
    "project": "Hello World",
    "version": "0.0.1",
    "language": "JavaScript",
    "dependencies": 1
  }
]

This also works on objects contained within a parent object. Using the previous example, if the objects were structured more like this:

{
  "project": "Awsome Project",
  "versions": {
    "lts": "1.0.0",
    "nightly": "1.0.1-SNAPSHOT"
  }
  "language": "JavaScript",
  "dependencies": 3
}

and I wanted to filter objects whose LTS version was 1.0.0 then the query object would look like this:

{
  "versions": {
    "lts": "1.0.0"
  }
}

A potential 'gotcha' with equality is that arrays are considered equal regardless of the order their elements appear in.

2. Expressions

It's possible to do more than just check for equality against fields on the input objects. It's also possible to use expressions to do more complex filtering. To go back to our previous example:

[
  {
    "project": "Awesome Project",
    "version:": "1.0.0",
    "language": "JavaScript",
    "dependencies": 3
  },
  {
    "project": "Superb Library",
    "version": "0.5.0",
    "language": "Java",
    "dependencies": 5
  },
  {
    "project": "Hello World",
    "version": "0.0.1",
    "language": "JavaScript",
    "dependencies": 1
  }
]

If we wished to filter the libraries with more than 1 dependency, we can use an expression. Expressions have two fields called op and value. op defines what operation will be used to perform the filtering, and value defines the target value. In our example, we want to filter on the dependencies field, and we want objects with more than 1 dependency. Hence, our query object would look like this:

{
  "dependencies": {
    "op": ">"
    "value": 1
  }
}

The resulting array would look like this:

[
  {
    "project": "Awesome Project",
    "version:": "1.0.0",
    "language": "JavaScript",
    "dependencies": 3
  },
  {
    "project": "Superb Library",
    "version": "0.5.0",
    "language": "Java",
    "dependencies": 5
  }
]

Expressions work for arrays, numbers and strings, with the available op values documented below:

Number Ops

  • > Requires that the input value is greater than the value field

  • < Requires that the input value is less than the value field

  • = Requires that the input value matches the value field

  • <= Requires that the input value is less than or equal to the value field

  • >= Requires that the input value is greater than or equal to the value field

  • != Requires that the input value in not equal to the value field

  • divisibleBy Requires that the input value be divisible by the value field

  • isIntegral Requires that the input value is a whole number if value is true, or requires that it is not if value is false

String Ops

  • != Requires that the input value does not match the value field

  • = Requires that the input value matches the value field. This is the same as using the above method of checking equivalance

  • like Requires that the value field is a substring of the input. The % sign is used to indicate where in the input string the substring is expected to be found.

Array Ops

  • contains Requires that an input value contain all elements in the value field

  • containsAny Requires that an input value contains 1 or more elements in the value field

  • = Requires that an input value contains all of the elements in the value field in any order

3. Compound Queries

It is possible to filter by more than one field at the same time. To call back to our previous examples, if we wanted to build a query object that filters by objects that have JavaScript in their language field, and have more than 1 dependency, then the query object would look like this:

{
  "language": "JavaScript",
  "dependencies": {
    "op": ">",
    "value": 1
  }
}

4. Boolean Logic

It's possible to use boolean logic on expressions. There or currently 3 logical operations, not, or and and.

not takes 1 sub-expression, whilst or and and can take any number of sub expressions. The boolean logic syntax for an operation that takes 1 sub expression is as follows:

field_name: {
  op: " /* string representing operation */ ",
  expression: {
    /* object representing an expression */
  }
}

The boolean logic syntax for an operation that takes multiple sub expressions is as follows:

field_name: {
  op: " /* string representing operation */ ",
  expressions: [
    /* array of objects representing expressions */
  ]
}
  • not Requires that the sub expression evaluates to false

  • and requires that all sub expressions evaluate to true

  • or requires that at least 1 sub expression evaluates to true

As an example, say I wanted to include all objects that have a first_name field with value 'John' or 'Fred'. I would represent it like this:

first_name: {
    op: "or",
    expressions: [
      {
        op: "=",
        value: "John"
      },
      {
        op: "=",
        value: "Fred"
      }
    ]
  }

5. Putting Field Names In Quotes

Putting quotes around a field name in the query as below:

"\"first_name\"": "John"

This is usefull if your input data use op or value as field names.

0.2.0

5 years ago

0.1.0

5 years ago

0.1.1

5 years ago

0.0.4

5 years ago

0.0.3

5 years ago

0.0.2

5 years ago

0.0.1

5 years ago