kriszyp / lmdb-js

Simple, efficient, ultra-fast, scalable data store wrapper for LMDB
Other
484 stars 39 forks source link

Range queries do not work with getValues #64

Closed vladar closed 2 years ago

vladar commented 3 years ago

Docs mention that when using dupSort it is possible to filter out values by range using getValues.

But it doesn't work for me (or maybe am I misinterpreting how this feature is supposed to work). Here is a repro:

const { open } = require("lmdb-store")

const store = open({
  name: `store`,
  path: process.cwd() + `/test`,
})

async function run() {
  const db = store.openDB({
    name: `db`,
    dupSort: true,
  })
  db.clear()
  let promise
  for (let i = 1; i < 5; i++) {
    promise = db.put(`key`, i)
  }
  await promise
  const range = { start: 1, end: 4 }
  const result = db.getValues(`key`, range)
  // expecting result to contain array [1, 2, 3] but it is empty:
  console.log(Array.from(result))
}

run().catch(e => console.error(e))
kriszyp commented 3 years ago

I don't think I intended to indicate that that was supported in the docs. The start and end are interpreted as ranges for the keys, not values (and that stored doesn't have any numeric keys). However, this seems like a good idea, and LMDB itself does support this types of cursor searches, so I will look into adding it (probably be a little ways out in a major version release).

vladar commented 3 years ago

Is there any workaround at a lower-level, maybe node-lmdb db/cursor for something like this for now?

vladar commented 3 years ago

I can probably workaround this with a binary search using getValuesCount and offset. But curious if getValuesCount makes sense in this context or maybe it's the same as just iterating through all values.

kriszyp commented 3 years ago

getValuesCount does iterate the cursor, but it doesn't return or deserialize any values, which makes it faster. The next version of lmdb-store I am working is streamlining the cursor iteration to reduce the number of native calls that are required for each iterating, which should make it faster, and that's where I was going to add support for the value ranges.

kriszyp commented 3 years ago

This should now be working and available in beta of v1.6.