itemsapi / itemsjs

Extremely fast faceted search engine in JavaScript - lightweight, flexible, and simple to use

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Conjunction between categries

ittocean opened this issue · comments

Hi,

A faceted search page in an application I am working on requires that the filter that is applied on the items acts as a conjunction of category disjunctions.

For example,
Having the following items -
items = [
{a: 1, b: 2},
{a: 2, b: 3}
{a: 2, b: 2} ]

With the following filters -
filters = {a: [1, 2], b: [2]}
My desired result would be = [
{a: 1, b: 2},
{a: 2, b: 2} ]

But actually I get = [
{a: 1, b: 2},
{a: 2, b: 3}
{a: 2, b: 2} ]

In other words I'm trying to get (a in (1,2) AND b = 2) but getting (a in (1,2) OR b = 2)...
I am unsure how (if possible) this can be done, and will appreciate some assistance. 😄

Thanks,
Ittai.

Hey Ittai,

Did you try conjunction false / true option in facets configuration (like in an example https://github.com/itemsapi/itemsjs/blob/master/docs/configuration.md) ?

Hey Mateusz,

The conjunction option applies on the aggregation attribute itself - for example if {a:[1,2,3]} and {a:[1,2,4]} and my filter was {a:[1,4]} then with conjunction=false you will get both objects, but with conjunction=true you will get only the second object.

This is not what I'm asking about. I'm pointing out that between two aggregations (two categories) a disjunction relation is applied.
For example, if my filter is {a:1, b:2} and I have objects {a:1,b:2} and {a:2, b:2} I'd get both in the result, while I really need the first object, because the condition needs to be (a=1 and b=2) not (a=1 or b=2).

Hey Ittai,

Could you provide a way from A-Z how you have achieved your results ? For me it seems you've made a typo somewhere. There is a conjunction between facets / categories by default

I've reproduced your case https://jsfiddle.net/cigol/dgkqosvx/17/ and seems to be working as you expected as you stated in your first post example:

Selection_341

Hi,

Thanks, JFiddle was helpful to describe and reproduce the issue I see.

I made the following alterations in script -
The following items

var items =  [
{a: 1, b: 2, c: 3, d: 3},
{a: 1, b: 3, c: 3, d: 3},
{a: 2, b: 3, c: 3, d: 3},
{a: 1, b: 2, c: 3, d: 3},
{a: 2, b: 3, c: 3, d: 3},
{a: 1, b: 2, c: 3, d: 3},
{a: 1, b: 3, c: 3, d: 3},
{a: 2, b: 3, c: 3, d: 3},
{a: 2, b: 2, c: 3, d: 3} ]

with the following aggregations

aggregations: {
    a: {
      title: 'Taks',
      conjunction: false,
      size: 10
    }, b: {
      title: 'Beee',
      conjunction: false,
      size: 10
    }, c: {
      title: 'Beeez',
      conjunction: false,
      size: 10
    }, d: {
      title: 'Beeex',
      conjunction: false,
      size: 10
    }
  }

I then check on the filters in the following order -
A = 1 --- I get overall 5 items which is correct.
B = 2 --- I get overall 3 items. This is still correct, but C and D show 6 items. I expected C 3 (3) and D 3 (3).
C = 3 --- I get overall 6 items which is incorrect.

Hey, please send also a link to JSFiddle so I could check it out

Hmm.. it seems to be a bug.. (it happens when 2 disjunctive facets are in use). There should be a conjunction between facet groups in all circumstances. Kudos for that case!

I'll fix it when I'll clean my backlog. Working with those sets calculations is challenging though

Feel free to create a PR if you are comfortable with JS and Algorithms.
The main algorithm for facets and items calculation is here: https://github.com/itemsapi/itemsjs/blob/master/src/facets.js#L71

Hey Ittai, I've fixed it. Please let me know if it solves your cases

Additionally I've refactored it so I am able to provide more flexible facets query logic if needed i.e.:

- facet_filters: [
  'a:1', // (single string)

  // a:1 AND b:2 (multiple strings)
  'a:1', 'b:2'

  // a:1 OR a:2 (multiple strings within an array)
  ['a:1', 'a:2'],

  // (a:1 OR a:2) AND b:2 (combined strings and arrays)
  ['a:1', 'a:2'], 'b:2',
]

Closing as it is fixed and no additional questions