finwo / lucene-filter

Data filter for lucene queries
MIT License
9 stars 6 forks source link

What does OR NOT operator do? #49

Open laggingreflex opened 4 years ago

laggingreflex commented 4 years ago
const data = [
  { name: 'C-3PO'           , description: 'Protocol droid.'                , species: 'Droid' },
  { name: 'R2-D2'           , description: 'Astromech droid built on Naboo.', species: 'Droid' },
  { name: 'Anakin Skywalker', description: 'Fallen Jedi, the chosen one.'   , species: 'Human' },
  { name: 'Obi-Wan Kenobi'  , description: 'Jedi Master.'                   , species: 'Human' },
  { name: 'Moon Moon'       , description: 'Mentally challenged wolf.'      , species: 'Wolf'  },
];
filter('Anakin OR NOT Kenobi')

What would/should this return?

Currently it returns both Anakin Skywalker and Obi-Wan Kenobi. Which is the same result if you'd have omitted the NOT.

Is it a bug that NOT is ignored here, or is it by design?

To me the OR NOT operator itself seems broken by design. Remember this is not a simple boolean expression, it's supposed to filter out rows from the data. To me, in plain English, the query "Anakin OR NOT Kenobi" reads somewhat like this:

  1. Get all rows that match "Anakin"

  2. OR - what does OR mean here? If Step 1 has any results, should it just return that?

  3. Get all rows that do NOT match "Kenobi" - i.e. all rows except "Obi-Wan Kenobi".

Step 3 will ALWAYS include the rows from Step 1, no?

To me, Anakin OR NOT Kenobi is same as just NOT Kenobi

Am I misunderstanding something?

finwo commented 4 years ago

At first glance, your assumption of Anakin OR NOT Kenobi being the same as NOT Kenobi sounds good.

Checking the code, the OR NOT operator negates the result from the right side, so 1 would become -1, and -5 would become 5.

The string filters return 0 when something doesn't match. -0 still returns 0, so you've stumbled upon a bug here (I should check how other implementations handle this case though)