yathit / ydn-db

Javascript database module for Indexeddb, Web SQL and localStorage storage mechanisms supporting version migration, advanced query, SQL and transaction.
Apache License 2.0
503 stars 41 forks source link

SortedMerge and bound keyrange doesn't make it #25

Open gpicavet opened 10 years ago

gpicavet commented 10 years ago

Hi, I would like to execute a query like that : "select id from storage where userId=toto and read=1 and date between date1 and date2"

Using SortedMerge on indexIterators doesnt give coherent result. I think the reason is that the bounded iterator isn't sorted by primary key. What would be the best way to solve it ? Imagine that i have other criterias (and possibly another date range)

Here is my code :

var schema = { stores : [{ name : "storage", keyPath : [ "id" ], indexes : [ { keyPath : [ "userId", "read"]}, { keyPath : [ "userId", "date"]}, ] }]}; ... var i1 = new ydn.db.IndexIterator("storage", "userId, read", ydn.db.keyrange.only(["toto",1])); var i2 = new ydn.db.IndexIterator("storage", "userId, date", ydn.db.keyrange.bound(["toto",new Date(0)], ["toto",new Date()]));

var out = []; var join_algo = new ydn.db.algo.SortedMerge(out); db.scan(join_algo, [i1, i2]).done( ... );

yathit commented 10 years ago

You will have to use ydn.db.algo.Zigzag. See Zigzag merge join.

gpicavet commented 10 years ago

with Zigzag, i have to postfix indexes with field "date" like that :

var i1 = new ydn.db.IndexIterator("storage", "userId, read, date", ydn.db.keyrange.bound(["toto",1,new Date(0)],["toto",1,new Date()])); var i2 = new ydn.db.IndexIterator("storage", "userId, date", ydn.db.keyrange.bound(["toto",dateFrom], ["toto",dateTo]));

=> OK it works :)

But suppose i have another date field to filter by range : var i3 = new ydn.db.IndexIterator("storage", "userId, dateModif, date", ydn.db.keyrange.bound(["toto",dateModifFrom, new Date(0)], ["toto",dateModifTo, new Date()]));

Can i include it in the scan ? It seems not to work. Do i have to filter with another key selection and do the merge myself ?

EDIT : i also have multientry indexes to filter on, but it doesn't allow compound path (so i cannot include date) => is it a limitation

yathit commented 10 years ago

Yes, according to current indexeddb specification, multiEntry is not supported in compound index. I have proposal, hopefully accepted in v2.

Since this is quite useful, I will think about prolyfill.