techfort / LokiJS

javascript embeddable / in-memory database
http:/techfort.github.io/LokiJS
MIT License
6.73k stars 482 forks source link

Column comparisons & Fix unique index bug #847

Closed radex closed 4 years ago

radex commented 4 years ago

Fixes #636.

This introduces a new class of filters, that do comparisons on document level, instead of on property level.

The key use case is allowing column comparisons, e.g. fetch all tasks where task.foo > task.bar. The syntax is this:

// simple column comparison
{ foo: { $$gt: 'bar' } } 

// for more flexibility, function can be passed
{ foo: { $$gt: doc => doc.bar + 1 } }

I took care not to affect hot path's performance. So I don't do any $$ checks — instead, all LokiOps now take a third argument (document) that's passed around - but only $$ops actually use it.

Nested filters - $or, $and, $not, $len, $size, $elemMatch all work.

I'm also thinking of adding object-level $filter .find({ $filter: (doc) => xxx }) and extending property-level $filter .find({ foo: { $filter: (foo, doc) => xxx } }) for object-level comparisons without having to completely resort to using .where(). But I didn't do it in this PR.

Additionally, I fix https://github.com/techfort/LokiJS/issues/839 here. Plain objects {} are not safe for use with arbitrary keys. Since Loki doesn't do ES6, I used prototype-less Objects to fix the issue.

radex commented 4 years ago

I hope so! I'm shipping this in production for the last couple of weeks and nothing broke :)