fergiemcdowall / search-index

A persistent, network resilient, full text search library for the browser and Node.js
MIT License
1.39k stars 149 forks source link

How to search date range? #542

Closed 1eeing closed 3 years ago

1eeing commented 3 years ago

I found that GTE and LTE need to pass in a string, but my date is number. I am worried that the result of string sorting is different from the result of number sorting. what should I do ??

fergiemcdowall commented 3 years ago

Simply cast the number to a string (999 + '' or String(999)). When you are sorting use TYPE: 'NUMERIC'.

fergiemcdowall commented 3 years ago

(actually you might not even need to cast to strings)

1eeing commented 3 years ago

Sorry, I made a mistake, I am worried that the result of RANGE by converting number to string will be problematic. E.g:

(async () => {
  const si = require('../../')
  const cars = [
    {
      _id: 0,
      make: 'Volvo',
      colour: 'Black',
      year: 2011,
      price: 2000,
      model: 'XC90',
      drivetrain: 'Hybrid'
    },
    {
      _id: 1,
      make: 'Tesla',
      colour: 'White',
      year: 2012,
      price: 300,
      model: 'S',
      drivetrain: 'Hybrid'
    },
    {
      _id: 2,
      make: 'Volvo',
      colour: 'Blue',
      year: 309,
      price: 4000,
      model: 'XC60',
      drivetrain: 'Hybrid'
    },
  ]

  const print = txt => console.log(JSON.stringify(txt, null, 2))
  const db = await si({ name: 'QUERY' })

  await db.PUT(cars)

  await db.QUERY({
    FIELD: ['price'],
    VALUE: {
      GTE: '2000',
      LTE: '4000'
    }
  }).then(print)
})()

The data item of price 300 has also been found.

1eeing commented 3 years ago

I want to find out the data of _id: 0 and _id: 2 based on GTE: 2000 and LTE: 4000, but can't work now.

1eeing commented 3 years ago

When I enter the number for GTE and LTE, I get an error: UnhandledPromiseRejectionWarning: TypeError: str.toLowerCase is not a function

fergiemcdowall commented 3 years ago

At the moment, a slight limitation of search-index is that numbers are treated as strings internally- this is something that will hopefully be improved in version 3. Therefore, if you want to numerically define ranges of numbers in version 2, you have to store them as left-padded strings (see .padStart for this):

(async () => {
  const si = require('search-index')
  const cars = [
    {
      _id: 0,
      make: 'Volvo',
      colour: 'Black',
      year: 2011,
      price: '2000',
      model: 'XC90',
      drivetrain: 'Hybrid'
    },
    {
      _id: 1,
      make: 'Tesla',
      colour: 'White',
      year: 2012,
      price: '0300',           // <- left padded with '0'
      model: 'S',
      drivetrain: 'Hybrid'
    },
    {
      _id: 2,
      make: 'Volvo',
      colour: 'Blue',
      year: 309,
      price: '4000',
      model: 'XC60',
      drivetrain: 'Hybrid'
    },
  ]

  const print = txt => console.log(JSON.stringify(txt, null, 2))
  const db = await si({ name: 'QUERY' })

  await db.PUT(cars)

  await db.QUERY({
    FIELD: ['price'],
    VALUE: {
      GTE: '2000',
      LTE: '4000'
    }
  }).then(print)
})()
1eeing commented 3 years ago

OK, I will try this. Thank you.

eklem commented 3 years ago

Let us now how it goes, @1eeing !