Name Last Update
..
coverage Loading commit data...
lib Loading commit data...
src Loading commit data...
test Loading commit data...
.babelrc Loading commit data...
.coveralls.yml Loading commit data...
.travis.yml Loading commit data...
MIT-LICENSE.txt Loading commit data...
README.md Loading commit data...
bower.json Loading commit data...
changelog.md Loading commit data...
gulpfile.js Loading commit data...
index.d.ts Loading commit data...
package.json Loading commit data...
sift.min.js Loading commit data...
tsconfig.json Loading commit data...
webpack.config.js Loading commit data...
yarn.lock Loading commit data...

validate objects & filter arrays with mongodb queries

Build Status

For extended documentation, checkout http://docs.mongodb.org/manual/reference/operator/query/

Features:

Node.js Examples


import sift from 'sift';

//intersecting arrays
var sifted = sift({ $in: ['hello','world'] }, ['hello','sifted','array!']); //['hello']

//regexp filter
var sifted = sift(/^j/, ['craig','john','jake']); //['john','jake']


//A *sifter* is returned if the second parameter is omitted
var testQuery = sift({

    //you can also filter against functions
    name: function(value) {
        return value.length == 5;
    }
});

//filtered: [{ name: 'craig' }]
[{
    name: 'craig',
},
{
    name: 'john'
},
{
    name: 'jake'
}].filter(testQuery);


//you can test *single values* against your custom sifter
testQuery({ name: 'sarah' }); //true
testQuery({ name: 'tim' }); //false\

Browser Examples

<html>
    <head>
        <script src="https://raw.github.com/crcn/sift.js/master/sift.min.js" type="text/javascript"></script>
        <script type="text/javascript">
            //regexp filter
            var sifted = sift(/^j/, ['craig','john','jake']); //['john','jake']
        </script>
    </head>
    <body>
    </body>
</html>

API

.sift(filter[, array][, selectorFn])

  • filter - the filter to use against the target array
  • array - sifts against target array. Without this, a function is returned
  • selectorFn - selector for the values within the array.

With an array:

sift({$exists:true}, ['craig',null]); //['craig']

Without an array, a sifter is returned:

var siftExists = sift({$exists:true});

siftExists('craig'); //true
siftExists(null); //false
['craig',null].filter(siftExists); //['craig']

With a selector:

var sifter = sift({$exists:true}, function(user) {
    return !!user.name;
});


sifter([
    {
        name: "Craig"
    },
    {
        name: null
    }
])

With your sifter, you can also test values:

siftExists(null); //false
siftExists('craig'); //true

Supported Operators:

See MongoDB's advanced queries for more info.

$in

array value must be $in the given query:

Intersecting two arrays:

//filtered: ['Brazil']
sift({ $in: ['Costa Rica','Brazil'] }, ['Brazil','Haiti','Peru','Chile']);

Here's another example. This acts more like the $or operator:

sift({ location: { $in: ['Costa Rica','Brazil'] } }, [ { name: 'Craig', location: 'Brazil' } ]);

$nin

Opposite of $in:

//filtered: ['Haiti','Peru','Chile']
sift({ $nin: ['Costa Rica','Brazil'] }, ['Brazil','Haiti','Peru','Chile']);

$exists

Checks if whether a value exists:

//filtered: ['Craig','Tim']
sift({ $exists: true }, ['Craig',null,'Tim']);

You can also filter out values that don't exist

//filtered: [{ name: 'Craig', city: 'Minneapolis' }]
sift({ city: { $exists: false } }, [ { name: 'Craig', city: 'Minneapolis' }, { name: 'Tim' }]);

$gte

Checks if a number is >= value:

//filtered: [2, 3]
sift({ $gte: 2 }, [0, 1, 2, 3]);

$gt

Checks if a number is > value:

//filtered: [3]
sift({ $gt: 2 }, [0, 1, 2, 3]);

$lte

Checks if a number is <= value.

//filtered: [0, 1, 2]
sift({ $lte: 2 }, [0, 1, 2, 3]);

$lt

Checks if number is < value.

//filtered: [0, 1]
sift({ $lt: 2 }, [0, 1, 2, 3]);

$eq

Checks if query === value. Note that $eq can be omitted. For $eq, and $ne

//filtered: [{ state: 'MN' }]
sift({ state: {$eq: 'MN' }}, [{ state: 'MN' }, { state: 'CA' }, { state: 'WI' }]);

Or:

//filtered: [{ state: 'MN' }]
sift({ state: 'MN' }, [{ state: 'MN' }, { state: 'CA' }, { state: 'WI' }]);

$ne

Checks if query !== value.

//filtered: [{ state: 'CA' }, { state: 'WI'}]
sift({ state: {$ne: 'MN' }}, [{ state: 'MN' }, { state: 'CA' }, { state: 'WI' }]);

$mod

Modulus:

//filtered: [300, 600]
sift({ $mod: [3, 0] }, [100, 200, 300, 400, 500, 600]);

$all

values must match everything in array:

//filtered: [ { tags: ['books','programming','travel' ]} ]
sift({ tags: {$all: ['books','programming'] }}, [
{ tags: ['books','programming','travel' ] },
{ tags: ['travel','cooking'] } ]);

$and

ability to use an array of expressions. All expressions must test true.

//filtered: [ { name: 'Craig', state: 'MN' }]

sift({ $and: [ { name: 'Craig' }, { state: 'MN' } ] }, [
{ name: 'Craig', state: 'MN' },
{ name: 'Tim', state: 'MN' },
{ name: 'Joe', state: 'CA' } ]);

$or

OR array of expressions.

//filtered: [ { name: 'Craig', state: 'MN' }, { name: 'Tim', state: 'MN' }]
sift({ $or: [ { name: 'Craig' }, { state: 'MN' } ] }, [
{ name: 'Craig', state: 'MN' },
{ name: 'Tim', state: 'MN' },
{ name: 'Joe', state: 'CA' } ]);

$nor

opposite of or:

//filtered: [ { name: 'Tim', state: 'MN' }, { name: 'Joe', state: 'CA' }]
sift({ $nor: [ { name: 'Craig' }, { state: 'MN' } ] }, [
{ name: 'Craig', state: 'MN' },
{ name: 'Tim', state: 'MN' },
{ name: 'Joe', state: 'CA' } ]);

$size

Matches an array - must match given size:

//filtered: ['food','cooking']
sift({ tags: { $size: 2 } }, [ { tags: ['food','cooking'] }, { tags: ['traveling'] }]);

$type

Matches a values based on the type

sift({ $type: Date }, [new Date(), 4342, 'hello world']); //returns single date
sift({ $type: String }, [new Date(), 4342, 'hello world']); //returns ['hello world']

$regex

Matches values based on the given regular expression

sift({ $regex: /^f/i, $nin: ["frank"] }, ["frank", "fred", "sam", "frost"]); // ["fred", "frost"]
sift({ $regex: "^f", $options: "i", $nin: ["frank"] }, ["frank", "fred", "sam", "frost"]); // ["fred", "frost"]

$where

Matches based on some javascript comparison

sift({ $where: "this.name === 'frank'" }, [{name:'frank'},{name:'joe'}]); // ["frank"]
sift({
    $where: function() {
        return this.name === "frank"
    }
}, [{name:'frank'},{name:'joe'}]); // ["frank"]

$elemMatch

Matches elements of array

var bills = [{
    month: 'july',
    casts: [{
        id: 1,
        value: 200
    },{
        id: 2,
        value: 1000
    }]
},
{
    month: 'august',
    casts: [{
        id: 3,
        value: 1000,
    }, {
        id: 4,
        value: 4000
    }]
}];

var result = sift({
    casts: {$elemMatch:{
        value: {$gt: 1000}
    }}
}, bills); // {month:'august', casts:[{id:3, value: 1000},{id: 4, value: 4000}]}

$not

Not expression:

sift({$not:{$in:['craig','tim']}}, ['craig','tim','jake']); //['jake']
sift({$not:{$size:5}}, ['craig','tim','jake']); //['tim','jake']

sub object Searching

var people = [{
    name: 'craig',
    address: {
        city: 'Minneapolis'
    }
},
{
    name: 'tim',
    address: {
        city: 'St. Paul'
    }
}];

var sifted = sift({ address: { city: 'Minneapolis' }}, people); // count = 1

//or
var sifted = sift({'address.city': 'minneapolis'}, people);//count = 1

Get index of first matching element

Get the index (0-based) of first matching element in target array. Returns -1 if no match is found.

import {indexOf as siftIndexOf} from 'sift';
var people = [{
    name: 'craig',
    address: {
        city: 'Minneapolis'
    }
},
{
    name: 'tim',
    address: {
        city: 'St. Paul'
    }
}];

var index = siftIndexOf({ address: { city: 'Minneapolis' }}, people); // index = 0