ongr-io / filtermanagerbundle Goto Github PK
View Code? Open in Web Editor NEWFilter manager bundle for product lists.
License: MIT License
Filter manager bundle for product lists.
License: MIT License
Currently every service for custom filter have to follow ongr_filter_manager.filter.filter_name
naming format because of this logic.
It should not be like that. Consider adding aliases for custom filters or change filters injection logic.
Currently the returned result count for the aggregations is default 10
I have tried to register custom filter like:
wdn_search.filters.wdn_match:
class: WDN\SearchBundle\Filters\WDNMatchSearch
arguments: ["search", "search"]
tags:
- { name: ongr_filter_manager.filter, manager: profile_list, filter_name: wdn_match }
<?php
namespace WDN\SearchBundle\Filters;
use ONGR\FilterManagerBundle\Filters\Widget\Search\MatchSearch;
class WDNMatchSearch extends MatchSearch
{
public function __construct($requestField, $field)
{
$this->setRequestField($requestField);
$this->setField($field);
}
}
But then i ran into the problems when setting that filter to work:
ongr_filter_manager:
managers:
profile_list:
filters:
- wdn_match
- visible
repository: 'es.manager.default.profile'
filters:
match:
visible:
request_field: 'visible'
field: visible
I get error:
ServiceNotFoundException in CheckExceptionOnInvalidReferenceBehaviorPass.php line 58:
The service "ongr_filter_manager.profile_list" has a dependency on a non-existent service "ongr_filter_manager.filter.wdn_match".
If i don't include the filter in list then i get results, but the filter is not applied (request url /searchtest?visible=true&search=somestring):
int(10)
array(2) {
["visibility"]=>
object(ONGR\FilterManagerBundle\Filters\ViewData)#8209 (4) {
["state":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
object(ONGR\FilterManagerBundle\Filters\FilterState)#8174 (4) {
["active":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
bool(true)
["value":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
string(4) "true"
["urlParameters":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
array(1) {
["visible"]=>
string(4) "true"
}
["name":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
string(10) "visibility"
}
["urlParameters":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
array(1) {
["visible"]=>
string(4) "true"
}
["resetUrlParameters":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
array(0) {
}
["name":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
string(10) "visibility"
}
["wdn_match"]=>
object(ONGR\FilterManagerBundle\Filters\ViewData)#8215 (4) {
["state":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
object(ONGR\FilterManagerBundle\Filters\FilterState)#8175 (4) {
["active":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
bool(false)
["value":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
NULL
["urlParameters":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
array(0) {
}
["name":"ONGR\FilterManagerBundle\Filters\FilterState":private]=>
string(9) "wdn_match"
}
["urlParameters":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
array(1) {
["visible"]=>
string(4) "true"
}
["resetUrlParameters":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
array(1) {
["visible"]=>
string(4) "true"
}
["name":"ONGR\FilterManagerBundle\Filters\ViewData":private]=>
string(9) "wdn_match"
}
}
Route config:
wdn_profile_search:
pattern: /searchtest
methods: [GET]
defaults:
_controller: WDNSearchBundle:Company:test
managerName: profile_list
Is there anything i don't understand or it's a bug?
Similar to ticket #105, we also need NOT AND filter. This is very useful in backend when one wants to exclude some information.
Our use case: select general tag PLANTS, and exclude DEAD_PLANTS leaving only alive ones. This widget greatly reduces the need to create tags and categories for every possible variation of combinations.
Our code:
/**
* Extends MultiTermChoiceAnd with 'not' functionality.
*/
class MultiTermChoiceAndNot extends MultiTermChoiceAnd
{
/** @var TermsFilter */
protected $filterNot;
/**
* {@inheritdoc}
*/
public function modifySearch(Search $search, FilterState $state = null, SearchRequest $request = null)
{
$this->filter = new TermsFilter($this->getField(), $state->getValue());
$this->filterNot = new NotFilter($this->filter);
$this->filterValues = $state->getValue();
if ($state && $state->isActive()) {
$search->addPostFilter($this->filterNot);
}
}
}
Please note that it's broken in a sense, that when adding new NOT terms, counts for new entries are a bit off in the widget. This is very subtle and happens, if newly excluded entries shares the same terms with already excluded entries.
Bundle provides default action to get response as JSON. It would be useful to have request parameter pretty
which would make response more human readable.
Filter manager builds filter list from configuration. In this process there are so many recursions and blocks rebuilding operations, just to make sure build correctly relations on selected filters.
What if we could cache all these builds and set only values to already builded list.
When using MatchSearch, if search term is removed and made empty, still no results are returned. This can be whitnessed in ongr sand box bundle:
http://ongr.dev/search?q=
In code:
Exception is thrown:
Attempted to call method "isRelevant" on class "ONGR\ElasticsearchBundle\DSL\Filter\TermFilter".
500 Internal Server Error - UndefinedMethodException
Exception is thrown, when we upgraded to ESB dev-master in our application.
Hello, why the filters doesn't implement JsonSerializable interface ?
Function score filter for boosting is missing. I'm going to implement it.
Any ideas or suggestions are welcome.
If you use 2 range filter on one page first filter rewrite second filter
Resolve:
/**
* {@inheritdoc}
*/
public function preProcessSearch(Search $search, Search $relatedSearch, FilterState $state = null)
{
$stateAgg = new StatsAggregation('range_agg'. $this->getField());
$stateAgg->setField($this->getField());
$search->addAggregation($stateAgg);
}
/**
* {@inheritdoc}
*/
public function getViewData(DocumentIterator $result, ViewData $data)
{
/** @var $data ViewData\RangeAwareViewData */
$data->setMinBounds($result->getAggregations()['range_agg' . $this->getField()]->getValue()['min']);
$data->setMaxBounds($result->getAggregations()['range_agg' . $this->getField()]->getValue()['max']);
return $data;
}
This filter does not look very useful and implies dependency from router bundle.
Remove it after documentation is prepared.
MatchSearch cannot be configured so that search would be in several fields
As a user i want to type in a ean and get exactly that product if found.
We should consider to remove all UI related logic ("max pages", "pages" range, etc).
Maybe would be good to remove requirement for adding filters in filter manager config and in the filter definitions node. What if user just starting to work and doesn't know yet how to work with this and want to debug a bit.
It won't change anything, but will add more flexibility.
There is a ticket #63, but it was converted to minimum_should_match ticket. We really need AND support. We contribute our implementation.
Notice duplication involved by not being override methods easily. Additional code is needed to allow showing correct counts when adding more terms to active multi-choice widget.
/**
* Overrides original MultiTermChoice behaviour and uses 'and' filter instead of default 'or'.
*/
class MultiTermChoiceAnd extends MultiTermChoice
{
/** @var TermsFilter */
protected $filter;
/** @var array */
protected $filterValues;
/**
* {@inheritdoc}
*/
public function modifySearch(Search $search, FilterState $state = null, SearchRequest $request = null)
{
$this->filter = new TermsFilter($this->getField(), $state->getValue(), ['execution' => 'and']);
$this->filterValues = $state->getValue();
if ($state && $state->isActive()) {
$search->addPostFilter($this->filter);
}
}
/**
* {@inheritdoc}
*/
public function preProcessSearch(Search $search, Search $relatedSearch, FilterState $state = null)
{
$name = $state ? $state->getName() : $this->getField();
$aggregation = new TermsAggregation($name);
$aggregation->setField($this->getField());
if ($this->getSortType()) {
$aggregation->setOrder($this->getSortType()['type'], $this->getSortType()['order']);
}
$aggregation->setSize(0);
if ($this->getSize() > 0) {
$aggregation->setSize($this->getSize());
}
if ($search->getPostFilters() && !$relatedSearch->getPostFilters()) {
$relatedSearch = $search;
}
if ($relatedSearch->getPostFilters()) {
$filterAggregation = new FilterAggregation($name . '-filter');
// Should add itself to aggregation so items counts would be set correctly.
if ($this->filterValues !== null) {
$relatedSearch->addPostFilter($this->filter);
}
$filterAggregation->setFilter($relatedSearch->getPostFilters());
$filterAggregation->addAggregation($aggregation);
$search->addAggregation($filterAggregation);
} else {
$search->addAggregation($aggregation);
}
}
}
Pager bundle as a standalone mostly does nothing. Its basically only one math divide operation. We should merge them.
otherwise you got query like:
"should": [
{
"match": {
"search phrase": {
"query": "title"
}
}
},
Also method execute()
could be renamed to handleRequest()
or other more descriptive name.
Hello,
I would like to create a custom filter and use it at multiple managers.
At this moment I am able to assign only one manager in filter service definition. I don't want to duplicate filter definitions, because there will be ~10 managers.
Any ideas how can I achieve or implement this?
ongr/pager-bundle is deprecated and now pager is part of filter manager.
Add mode support (http://www.elastic.co/guide/en/elasticsearch/reference/1.5/search-request-sort.html#_sort_mode_option) to sort filter widget
ONGR\FilterManagerBundle\DependencyInjection\Configuration line 88
Defining the initRuntime() method in the "ongr_pager" extension is deprecated. Use the
needs_environmentoption to get the Twig_Environment instance in filters, functions, or tests; or explicitly implement Twig_Extension_InitRuntimeInterface if needed (not recommended).
Implement ability to add custom filters through symfony's dependency injection tags
Range filter widget throws Exception when passed range arguments are malformed.
public function getState(Request $request)
{
$state = parent::getState($request);
if (!$state->isActive()) {
return $state;
}
$values = explode(';', $state->getValue(), 2);
if (count($values) < 2) {
throw new \UnderflowException(
"Range request field value must contain from, to values delimited by ';', got {$state->getValue()}."
);
}
$normalized['gt'] = (int)$values[0];
$normalized['lt'] = (int)$values[1];
$state->setValue($normalized);
return $state;
}
Maybe would be better to set filter as inactive and execute request without it than throw exception.
if (count($values) < 2) {
$state->setActive(false);
return $state;
}
Edit: There is explanation in configuration section rather than index page.
f.e. If we want to use filter manager in other components we define our filter manager without configuration. When user would use a component (which needs filter manager to be added in bundles array) FMB requires minimal configuration with one filter and manager, which would be left unused.
Function ongr_paginate_path
is not safe!
Must be 'is_safe' => []
.
Also HHVM build should be interesting.
Tests fails because of new deprecations.
https://travis-ci.org/ongr-io/FilterManagerBundle/builds/64904797
Now we define one ESB manager for all
and repositories are taken only from that manager.We should be able to define repositories like es.manager.default.product
Basically we need to support products with variants. The first question is how the data is indexed. If the variation information is provided inside some field, then there is nothing to do, this is simple choice filter. Otherwise if each variant stands as single document we have to think about grouping filter.
Add configurable execution mode support (http://www.elastic.co/guide/en/elasticsearch/reference/1.x/query-dsl-terms-filter.html#_execution_mode) to MultiTermChoice widget
Current configuration for custom filters is too complicated. To use single custom filter with multiple filter managers user must add multiple tags (single tag for each manager).
We should leave single tag here with "filter name" attribute and create alias ongr_filter_manager.FILTER_NAME
, so custom filter could be used in configuration like any others.
Another idea: we could even provide a way to extend configuration tree for custom filter types.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.