finwo / lucene-filter

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

NOT operator #76

Open paulcanning opened 2 years ago

paulcanning commented 2 years ago

Trying to figure out how to implement the NOT operator, using the same style of the others.

module.exports = (l, r) => (data) => {
  let rl = l(data);
  let rr = r(data);
  let rla = Math.abs(rl);
  let rra = Math.abs(rr);
  return rla !== rra;
};

This is giving me promising results, eg

console.log(data.filter(lucene('species:human NOT description:master')));

[
  {
    name: 'Anakin Skywalker',
    description: 'Fallen Jedi, the chosen one.',
    species: 'Human'
  }
]

But then flops with something like

console.log(data.filter(lucene('species:human NOT name:o')));

// should be
[
  {
    name: 'Anakin Skywalker',
    description: 'Fallen Jedi, the chosen one.',
    species: 'Human'
  }
]

// actual result
[
  { name: 'C-3PO', description: 'Protocol droid.', species: 'Droid' },
  {
    name: 'Anakin Skywalker',
    description: 'Fallen Jedi, the chosen one.',
    species: 'Human'
  },
  {
    name: 'Moon Moon',
    description: 'Mentally challenged wolf.',
    species: 'Wolf'
  }
]

No idea how it's so broken, but like I mentioned in another issue, I don't really understand the logic used in the operators yet. This is just a first stab in the dark at the NOT operator.

finwo commented 2 years ago

The original idea of the NOT operator was that it'd revert the result of the matcher, basically subtracting points from the end-result if the matcher reports it's matching.

There's a high chance I have not implemented that basic idea properly though

paulcanning commented 2 years ago

Bit more fiddling, and this seems to give better results

module.exports = (l, r) => (data) => {
  let rl = l(data);
  let rr = r(data);

  if (rl > rr) {
    return rl;
  }

  return 0;
};