Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

search on joined data #17

Open
twilly86 opened this issue Dec 21, 2016 · 9 comments
Open

search on joined data #17

twilly86 opened this issue Dec 21, 2016 · 9 comments

Comments

@twilly86
Copy link

I was using predicate builder prior to switching to your library and was doing searches on joined data.
Example..

 var predicateF = PredicateBuilder.New<PurchaseOrder>()
                        .Or(f =>f.Vendor.Name.Contains(parms.searchText))
                        .Or(f => f.LineItems.Any(y => y.StrainName.Contains(parms.searchText)))
                        .Or(f => f.LineItems.Any(y => y.ToComplianceId.Contains(parms.searchText)))
                        .Or(f => f.LineItems.Any(y => y.ComplianceId.Contains(parms.searchText)))
                        .Or(f => f.Manifest.ComplianceId.Contains(parms.searchText))

Is this possible?

@ninjanye
Copy link
Owner

Hi @twilly86, I'm assuming you've tried to complete this using SearchExtensions. Be great if this was supported. I'm currently working on another issue but will try and put some time in to see if there is a quick win here to be had.

1 similar comment
@ninjanye
Copy link
Owner

Hi @twilly86, I'm assuming you've tried to complete this using SearchExtensions. Be great if this was supported. I'm currently working on another issue but will try and put some time in to see if there is a quick win here to be had.

@Prefsmaster
Copy link

Hi!
What is the status on this issue?
We could really use this!

@ninjanye
Copy link
Owner

Hi @Prefsmaster

Thanks for giving this a bump. It's been a while since I looked over this issue and it has gone stale as a result, so apologies for that.

Could you clarify what functionality it is you would like to support?

We do have SearchChildren functionality which allows you to do something like:

var result = testData.SearchChildren(x => Children)
                         .With(c => c.Name).Containing("rob")
                         .With(c => c.Age).GreaterThan(20)

But I'm guessing this does not meet your needs

@Prefsmaster
Copy link

Hey, thanks for the quick response, I will take a look at SearchChildren, but fear it may not get the job done.
Here's some more context:

We have a bunch of tags hanging off an entity, and I want to select all entities where some properties or one of the attached tags contains any of the (array of) substrings.

We had a previous implementation that could search for only one string:

IQueriable<Person> Persons = _repository.Persons;
Persons = Persons.Where(p => p.FirstName.Contains(substring) ||
                     p.LastName.Contains(substring) ||
                     p.Tags.Any(t.Tag.Contains(substring));

but now we want to be able to search for multiple substrings in both the parent and the child-entities.
Your package seemed a good start, and we tried this:

Persons = Persons.Search(
                    p => p.FirstName,
                    p => p.LastName,
                    // also search in tags, turn them into one large string and search that,
                     p => string.Join(" ", p.Tags.Select(t => t.Tag))
                ).Containing(substrings);

But Linq to Entities doesn's support the string.Join (nor Aggregate).

So that's why I bumped this issue :-)
Ferenc

@ninjanye
Copy link
Owner

ninjanye commented Feb 28, 2019

This is by no means a nice solution but could something like this work to get you going?

var nameMatch = persons.Search(x => x.FirstName, x => x.LastName).Containing(searchTerms);
var tagMatch = persons.SearchChildren(x => x.Tags).With(x => x).Containing(searchTerms);

var result = name.Union(tagMatch);

@Prefsmaster
Copy link

Thanks again!
This works and ALMOST gets the job done.
Can the tagmatch be extended to find the terms only for those tags where another property of the Tag has a specific IdValue?
Reading the documentation it seems to be possible to achieve something like

p.Tags.Any(t => t.ManagerId == manager.Id && t.Tag.Contains(searchTerms))

so only the tags added by the provided manager are searched/returned.
Can this be acheved by concatenating SearchChildren clauses just like Searches?

cheers!
Ferenc

@ninjanye
Copy link
Owner

ninjanye commented Mar 1, 2019

If I understand correctly, then maybe something like this...

var nameMatch = persons.Search(x => x.FirstName, x => x.LastName).Containing(searchTerms);
var tagMatch = persons.SearchChildren(x => x.Tags)
                      .With(t => t.ManagerId).EqualTo(managerId)
                      .With(t => t.Tag).Containing(searchTerms);
var result = name.Union(tagMatch);

@Prefsmaster
Copy link

Somehow I made a mistake earlier.
Just tried to implement your latest idea, but that didn't work.
I took out the '.With(x => x.ManagerId).EqualTo(managerId)' part and replaced your 'With(x => x)' with 'With(x => x.TagText)' to make the code compile.
However the remaining code

                    persons.SearchChildren(x => x.Tags) // search in tags added to this person
                        .With(t => t.TagText).Containing(substrings);

now somehow yields all persons, not only the ones tagged with a tag containing the substring(s).
I am confused now... :-)
again thanks for all your support!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants