k-samuel / faceted-search

PHP Faceted search library
MIT License
205 stars 14 forks source link

Changing the AND/OR search #33

Closed janroz closed 9 months ago

janroz commented 9 months ago

Hello,

I would like to ask if it is possible to change the search logic from OR to AND for specific groups of filters. Sometimes it is useful when all the options within one group are suitable.

Alternatively, direct me how it would be most appropriate to implement a similar functionality.

Maybe something like:

$filters[] = new ValueFilter('some_value', $data['some_value'], 'AND');

k-samuel commented 9 months ago

Hello. I don't fully understand what behavior is expected when using such filter. Can you give me an example of a real-life case?

You can pass an array as field value and search will use "OR" inside this field. Different fields uses "AND" intersection.

For example:

Find phones with memory sizes ANY OF 12, 32, 64

$filters[] = new ValueFilter(‘size’, [12,32,64]);

Find phones with memory sizes ANY OF (12, 32, 64) AND camera 12m

$filters[] = new ValueFilter(‘size’, [12,32,64]);
$filters[] = new ValueFilter(‘camera’, [12]);

Find phones with memory size 32gb AND camera 16m

$filters[] = new ValueFilter(‘size’, [32]);
$filters[] = new ValueFilter(‘camera’, [16]);

Query with selected filters:

$query = (new SearchQuery())->filters($filters);
$records = $search->query($query);
janroz commented 9 months ago

Hello,

ok, here's a real world usage example. Product have something like brand and usage. For example shop with photo equipment. Lenses can have a brand (Sony, Nikon, Canon, Sigma) and recommended usage. Usage can be like for weddings, for streetphoto, for portraits, for wildlife.

And now filters:

$filters[] = new ValueFilter(‘brand’, [133, 155]); // Sigma or sony - here is operator OR
$filters[] = new ValueFilter(‘usage’, [2, 3]); // portraits and wildlife - here should be operator AND

Do you think there is any way to achieve this?

k-samuel commented 9 months ago

Now I understand. There is no such functionality yet, I’ll make an experimental branch and see how it can be implemented and how difficult it is

janroz commented 9 months ago

Thank you! Maybe I can help with some work around it

k-samuel commented 9 months ago

Created a pull request with the necessary functionality. https://github.com/k-samuel/faceted-search/pull/35

You would help me a lot if you looked at the new opportunity and how well it meets your expectations. It would be nice to test it on your case.

If everything is ok I will add more test cases

janroz commented 9 months ago

Works perfectly, super fast and accurate. Only one thing is wrong there - it's not returning the correct counts. I will try to solve the problem.

k-samuel commented 9 months ago

Can you share test data sample, filters setup and expected correct counts? I can create test case on it and figure out whats going wrong.

janroz commented 9 months ago

Sure! I will prepare some data sample.

k-samuel commented 9 months ago

Thanks, I'll take a closer look and try to figure it out. It is worth considering that aggregates exclude property self-filtering to allow the user to choose another option in the interface.

Example: The user wants a phone with 32GB memory, checks the box for the desired option (16, 32, 64). If self-filtering is not excluded, then all other options in the interface will disappear and only 32 will remain. Thus, he will not be able to change his choice.

The filter value on a specific field during aggregation is used to filter values only for other fields. Example: the size condition intersects with the brand field data to limit the list of brand variations.

It can’t be that it’s this logic that’s confusing? The example can be run and viewed in the demo folder.

Perhaps the setting for using self-filtering should be taken out and made available for selection.

It all depends on the use case of the library. Initially, the library was developed to simplify the construction of a search UI. If you want to use the library at the level of technical analysis, statistics, etc. , then I should think about how to give the opportunity to select a self-filtering condition.

k-samuel commented 9 months ago

Updated PR with new self-filtering option

$query = (new AggregationQuery())->filters($filters)->countItems()->sort()->selfFiltering(true);

Still working on a test case with films.

janroz commented 9 months ago

Looks great, looks like it does exactly what I described. Perfect work. I will test it tomorrow more.

BTW I implemented simple functionality search range in range as I ask some days ago. Not ideal but works good.

janroz commented 9 months ago

Take a look at for example https://fontawesome.com/v6/search?o=r&m=free

There are also facet filters on the left side. When you choose any of the options in the "category" it is exactly what I described earlier. For example, if you select "alert" and "energy", you will see items that have the categories alert AND energy. But if you search by style, you'll see solid OR regular items.

So I don't thing it's confusing, it is really usefull. Sometimes, not always.

IMDB has a similar feature, check it out: https://www.imdb.com/search/title/?genres=action,adventure,animation try changing something in the genres on the left side, you'll see the overall results go down as you select more and more. These are the features I wanted. If you choose action, adventure, and animation, imdb will return movies that all have those categories (AND).

k-samuel commented 9 months ago

Fixed bug in self-filtering scenario. Now you can check your case using ->selfFiltering(true). Cool feature with "AND" condition. I didn’t think about it and the need didn’t arise. Typically worked with eCommerce and products with a single value attributes

Interesting examples.

Imdb - has no values count so our disscussion about aggregates is not about it.

fontawsome - As i think made UI mistake. They useed self filtering with hiding variants. Most likely, they use ElasticSearch where it is quite difficult to disable self-filtering. Balance between complexibility and user friendliness I have an article about such cases: https://habr.com/ru/articles/595765/

Nevertheless, now you can implement it using the library.

janroz commented 9 months ago

Works perfect! I tested it out and it's is awesome. Thank you.

k-samuel commented 9 months ago

Great. If all is well, I will release a new version.

k-samuel commented 9 months ago

Released in 3.2.0