Biarity / Sieve

⚗️ Clean & extensible Sorting, Filtering, and Pagination for ASP.NET Core

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Filter on multiple properties (OR condition)

fruel opened this issue · comments

I have been playing with Sieve over the last few days and it is really cool.

However, one feature that I think is missing, is the ability to express filters like this:
"If property1 or property2 contain ABC"

I imagine that the {Name} part of the filter expressions could be extended like this:
(property1,property2)@=ABC

What do you think about this?

You can do that with a custom filters so for example:

The equivalent of your (title, body, author)@=ABC would be PostSearch@=ABC with:

public class SieveCustomFilterMethods : ISieveCustomFilterMethods
{
    public IQueryable<Post> PostSearch(IQueryable<Post> source, string op, string value)
    {
        if (op == "@=")
        {
            var result = source.Where(p => p.Title.Contains(value)
                            || p.Body.Contains(value)
                            || p.Author.Contains(value));
            return result;
        }
        else
        {
            return source;
        }
    }
}

This would save you having to send requests with the same property names repeated every time, as well as allow for any additional logic you might need.


That being said, I understand the need for OR logic, especially when you need to query unknown arbitrary parameters each time. I was working on an version where a | would donate OR (similar to , currently denoting AND). I think this would allow for more complex logic than your suggested implementation - at the cost of being less concise and more redundant (ie. instead of (p1,p1)@=ABC, you'd have p1@=ABC|p2@=ABC. Let me know what you think - would that work for your use case or am I missing something?

Really glad you like Sieve :D.

Thanks for your quick response.

Yes, a complete OR logic using | was also a thought of mine and would work for me as well.

One difference I can think of is that with a generic OR solution, operator precedence between AND and OR has to be considered when combining operators. Should it be like in C# (AND before OR) or just an evaluation from left to right? Are brackets needed to group expressions?

After using Sieve a bit more, I found that I didn't need this feature often (usually custom filters worked fine). But given how easy it is to implement OR logic similar to what you described (c861ada), I'll be including it as part of v2. The feature is ready on the master branch but still not published to nuget yet.

I find the current parsing code to be a bit hacky - so I'll be trying to rewrite this using a parsing framework next to maybe support better AND/OR logic with precedence and bracket grouping but that's not a priority for now.

EDIT: v2 on nuget now (but review this before upgrading)

Loving Sieve - it's great! Upvoting this... I'd love this to work:

{{url}}collector?sorts=Name&filters=(Name|Description)@=A

I just tried it - it didn't work :( The Name contained 'A', but the Description didn't. Bug?

Could you please open a new issue with error details?

Hi @Biarity , sorry for commenting on an closed issue but I found the OR condition is not fully working

I understand filters=(name|email)@=gmail translate as name contains 'gmail' OR email contains 'gmail'
However, when I try filters=email@=gmail|name@=son, this is wrongly translated as email contains 'gmail' OR email contains 'name'

What I expect is email contains 'gmail' OR name contains 'son'

Am I using the OR condition wrong or is it this a bug?
Or is it intended for

You can also have multiple values (for OR logic) by using a pipe delimiter, eg. Title@=new|hot will return posts with titles that contain the text "new" or "hot"

If so how can I do the OR condition with difference name value?
I am pretty sure filters=(email@=gmail)|(name@=son) is not working either. Nothing is filtered with this.

Yeah, OR conditions work exclusively for names or values, not whole filters. I guess the closest to what you want would be (name|email)@=gmail|son, which is still not quite what you want. Hopefully a future rewrite of the parser would allow thta kind of query but until then you can easily implement this via custom filters.

I think it is also better if the README.md include actual examples for the OR operations, as it is now pointed to #8 (comment) which is not what the final implementation.
Where filters=(fieldNameA|fieldNameB)@=valueA|valueB need bracket for the fields and no bracket for the values.

Also, when implementing the custom filter, I found #47 where it will conflict with the FluentAPI

filters=name=sam
is their something like filters=sam, where i don't have to specify the "parameter", so I can make the searching more universal (Generalised)

Hi,
Is it possible maybe in another version of sieve to add search based on fields whitch we already set to be filtered?
Instaed of sending 10 fields to be sorted (filed1,field2,...field10) @= something to send some univerzal verb to filter through all fields whitch are set up to be filtered ?
For example my model looks like:

    [Sieve(CanFilter = true, CanSort = true)]
    public string FirstName { get; set; } = string.Empty;

    [Sieve(CanFilter = true, CanSort = true)]
    public string LastName { get; set; } = string.Empty;

    [Sieve(CanFilter = true, CanSort = true)]
    public string Place { get; set; } = string.Empty;

I want to be filtered firstname, lastname, and place by default all what is set up by sieve in data ano...
Thanks