Compound Index filtering question

88 views
Skip to first unread message

Andrew Holbrook

unread,
May 26, 2015, 10:49:44 PM5/26/15
to dex...@googlegroups.com
Hi,

Just discovered your library today after futzing around the past 2 weeks with another IndexedDB library with confusing (and often outdated) documentation.  Great work!

I have a dataset that is structured like so:
Animal | NumberOfLegs | FurColor

Is there a way to create a single compound index, for example [Animal + NumberOfLegs + FurColor] where I can filter only by 1 or two of those, eg.

db.data.where('[Animal+NumberOfLegs+FurColor]').equals([null,'4','brown']) or 
db.data.where('[Animal+NumberOfLegs+FurColor]').equals(['spiders,'8',null])

Otherwise, I assume I can make combinations of indices, but the number or indices will add up quickly.

Thanks!
Drew

David Fahlander

unread,
May 27, 2015, 4:52:52 AM5/27/15
to dex...@googlegroups.com, andrew....@gmail.com
Hi!

You can always do queries on the leading keys (using where('[Animal+NumberOfLegs+FurColor]').between(["Horse",4, ""], ["Monkey", 2, '\uffff'])) but if you want to search on trailing keys you need to index them separately. Mapping your specific example to an implementation, you would write:

db.version(x).stores({
    data: 'Id, [Animal+NumberOfLegs+FurColor], [NumberOfLegs+FurColor]'
});

// Your sample: db.data.where('[Animal+NumberOfLegs+FurColor]').equals([null,'4','brown']) would instead be:
db.data.where('[NumberOfLegs+FurColor]').equals(['4','brown'])

// Your sample: db.data.where('[Animal+NumberOfLegs+FurColor]').equals(['spiders,'8',null]) would instead be:
db.data.where('[Animal+NumberOfLegs+FurColor]').between(['spiders', 8, ''], ['spiders', 8, '\uffff'])

Andrew Holbrook

unread,
May 28, 2015, 2:34:28 AM5/28/15
to dex...@googlegroups.com, andrew....@gmail.com
Thanks, David!

Andrew Holbrook

unread,
May 28, 2015, 2:55:06 AM5/28/15
to dex...@googlegroups.com
To tag onto this, is there an equivalent "startsWith" compound index command?  Using the example below (getting all 8 legged spiders whose color starts with "b"), would it be:

db.data.where('[Animal+NumberOfLegs+FurColor]').between(['spiders', 8, 'b'], ['spiders', 8, '\uffff'])

Thanks!

Andrew Holbrook

unread,
May 28, 2015, 11:52:55 AM5/28/15
to dex...@googlegroups.com
And to answer my own question, yes.

David Fahlander

unread,
May 29, 2015, 4:24:46 AM5/29/15
to dex...@googlegroups.com, andrew....@gmail.com
Yes, but replace "\uffff" with "b\uffff".

vali....@gmail.com

unread,
Sep 5, 2015, 8:09:16 AM9/5/15
to Dexie.js
Hi David,
Thanks for your help with quick responses. Even i got into some trouble like same as Andrew. This is what i'm trying to do.

login ='jh...@gmail.com';
time = new Date().getTime();
lowerBound = [login,0,'file-transfer'];
upperBound = [login,time,'file-transfer'];
transcriptIndex = "[login+dateInMilliseconds+label]";
db.chatTranscripts.where(transcriptIndex).between(lowerBound,upperBound).reverse().toArray(function(data){
console.log(data);

}).catch(function(error){
console.error(error);
});

But the query is giving all objects with the current index. Basically i was trying to implement filters. Please help me with this and let me know if any further information needed.

raymon...@gmail.com

unread,
Oct 9, 2015, 2:22:39 PM10/9/15
to Dexie.js
On Tuesday, May 26, 2015 at 9:49:44 PM UTC-5, Andrew Holbrook wrote:
> Hi,
>
>
> Just discovered your library today after futzing around the past 2 weeks with another IndexedDB library with confusing (and often outdated) documentation.  Great work!
>

I'm trying to get this too. I've got "people" objects and I want to index on first and last name:

myDb.version(1).stores({
employees:"++id,&email,[name.first+name.last]"
});

I've got a person in the db, aaron boyd, and if I search for a/b like so:

myDb.employees.where("[name.first+name.last]").startsWithIgnoreCase([fName,lName]).each(function(emp) {
console.log('found match '+emp.name.first);
});

I'd expect to find it. Shouldn't that work?



Raymond Camden

unread,
Oct 9, 2015, 2:28:17 PM10/9/15
to Dexie.js
So I realize my where should not have [ ] in it. But removing it didn't help.

Raymond Camden

unread,
Oct 9, 2015, 2:31:31 PM10/9/15
to Dexie.js
Ok so I was wrong, [] was required. :)

So I can make this work:

    myDb.employees.where("[name.first+name.last]").equals([fName,lName]).each(function(emp) {
        console.log('eq found match '+emp.name.first);
    });   

but not a startsWithIgnoreCase example.

Raymond Camden

unread,
Oct 9, 2015, 3:48:46 PM10/9/15
to Dexie.js
And as an aside, I also tried storing first name and last name in the
'root' of my object to see if that would help, but it did not.
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "Dexie.js" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/dexiejs/K2aJr62XNTQ/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> dexiejs+u...@googlegroups.com.
> Visit this group at http://groups.google.com/group/dexiejs.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/dexiejs/e46cd7f2-53c8-463d-b500-07ad4e717a1b%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.



--
===========================================================================
Raymond Camden, Developer Advocate for MobileFirst at IBM

Email : raymon...@gmail.com
Blog : www.raymondcamden.com
Twitter: raymondcamden

David Fahlander

unread,
Oct 9, 2015, 7:31:47 PM10/9/15
to Raymond Camden, Dexie. js

Unfortunately, startsWith () and startsWithIgnoreCase () cannot be used with arrays / compound keys but requires a string as its single argument.

You could use the between () operator but then it would only be able to compare case sensitively. (Similar to earlier question in this thread.)

David Fahlander

unread,
Oct 9, 2015, 7:39:05 PM10/9/15
to Dexie.js
@vali, to answer your question, you would have to index like this :

"[login+label+dateInMilliseconds]"

Instead of :

"[login+dateInMilliseconds+label]"

And then query accordingly. Otherwise ask labels for that login may be returned

Raymond Camden

unread,
Oct 10, 2015, 8:52:05 AM10/10/15
to David Fahlander, Dexie. js
Fair enough - is that documented?

Vali Shah

unread,
Nov 19, 2015, 11:41:50 AM11/19/15
to Dexie.js
Hi David, 
  Thanks a lot. That solution worked. I made a mistake while configuring index. 


Reply all
Reply to author
Forward
0 new messages