Allow the searching of child collections #4

Closed
ninjanye opened this Issue Sep 18, 2015 · 13 comments

Projects

None yet

2 participants

@ninjanye
Owner

Investigate the possibility of have SearchExtensions return a parent item if a match is found in a child collection.

A possible example might be:

Given I have a collection of Shops,
I want to return all shops that stock a product with a Name containing "football".

Additionally, support for non strings should be considered:

Given I have a collection of Shops,
I want to return all shops that stock a product with a Price greater than 10.

@bzbetty - does this adequately fulfill what you were lookng for?

@ninjanye ninjanye self-assigned this Sep 18, 2015
@bzbetty
bzbetty commented Sep 18, 2015

That sounds perfect.

@ninjanye
Owner

Hi @bzbetty,

I have just released an update to SearchExtensions which partly addresses this issue. With version 1.7 you can now search child collections. The reason this is only partly complete is because it is currently only enabled for IEnumerable collections meaning that the filtering is done in memory. IQueryable is still to come.

I have created a blog post explaining how to use the new feature, but in short, with the examples above in mind, you can now do something like the following:

var result = _shops.SearchChildren(s => s.Products)
                   .With(p => p.Name)
                   .Containing("football");

OR

var result = _shops.SearchChildren(s => s.Products)
                   .With(p => p.Price)
                   .GreaterThan(10);

I'll be working on supporting IQueryable next so that hopefully the server can do the work instead of doing the filtering in memory.

@bzbetty
bzbetty commented Oct 31, 2015

Awesome! Will try it out as soon as I get the chance.
On 22 Oct 2015 10:12, "John Nye" notifications@github.com wrote:

Hi @bzbetty https://github.com/bzbetty,

I have just released an update to SearchExtensions which partly addresses
this issue. With version 1.7 you can now search child collections. The
reason this is only partly complete is because it is currently only enabled
for IEnumerable collections meaning that the filtering is done in memory.
IQueryable is still to come.

I have created a blog post explaining how to use the new feature
http://jnye.co/Posts/2045/search-extensions-search-within-child-collections-now-supported-in-v1-7,
but in short, with the examples above in mind, you can now do something
like the following:

var result = _shops.SearchChildren(s => s.Products)
.With(p => p.Name)
.Containing("football");

OR

var result = _shops.SearchChildren(s => s.Products)
.With(p => p.Price)
.GreaterThan(10);

I'll be working on supporting IQueryable next so that hopefully the
server can do the work instead of doing the filtering in memory.


Reply to this email directly or view it on GitHub
#4 (comment)
.

@ninjanye
Owner
ninjanye commented Nov 5, 2015

Big news! I have just made a second release which now supports searching on IQueryable. This means that the filtering is all pushed down to the server meaning you only retrieve the matching records.

Blog post to follow

@ninjanye ninjanye closed this Nov 5, 2015
@bzbetty
bzbetty commented Nov 5, 2015

you are too awesome!

On Thu, Nov 5, 2015 at 1:21 PM, John Nye notifications@github.com wrote:

Big news! I have just made a second release which now supports searching
on IQueryable. This means that the filtering is all pushed down to the
server meaning you only retrieve the matching records.

Blog post to follow


Reply to this email directly or view it on GitHub
#4 (comment)
.

@bzbetty
bzbetty commented Dec 17, 2015

Is it possible to use a Search and a SearchChildren at the same time? It
looks like chaining them in C# will perform a AND query instead of an OR
query?

eg

SELECT [Extent1].[Id] AS [Id]
-- Additional columns --
FROM [dbo].[Shops] AS [Extent1]
WHERE
[Extent1].Name like '%ball%'
or
EXISTS (
SELECT 1 AS [C1]
FROM [dbo].[Products] AS [Extent2]
WHERE ([Extent1].[Id] = [Extent2].[Shop_Id])
AND ([Extent2].[Name] LIKE N'%ball%')
)

On Thu, Nov 5, 2015 at 1:22 PM, Sam McKoy smckoy@gmail.com wrote:

you are too awesome!

On Thu, Nov 5, 2015 at 1:21 PM, John Nye notifications@github.com wrote:

Big news! I have just made a second release which now supports searching
on IQueryable. This means that the filtering is all pushed down to the
server meaning you only retrieve the matching records.

Blog post to follow


Reply to this email directly or view it on GitHub
#4 (comment)
.

@ninjanye
Owner

Can you post the code you are using to try this? I think it should be possible with the current code base

@bzbetty
bzbetty commented Dec 18, 2015

Context.Invoices
.Search(invoice => invoice.Description).ContainingAll(searchTerms)
.SearchChildren(invoice => invoice.Client).With(client =>
client.Name).ContainingAll(searchTerms)

also tried

Context.Invoices
.Search(invoice => invoice.Description)
.SearchChildren(invoice => invoice.Client).With(client =>
client.Name).ContainingAll(searchTerms)

On Fri, Dec 18, 2015 at 8:45 PM, John Nye notifications@github.com wrote:

Can you post the code you are using to try this? I think it should be
possible with the current code base


Reply to this email directly or view it on GitHub
#4 (comment)
.

@ninjanye
Owner

Hmmm, I would have thought the first option would have done the trick. I'll be on the train to work in a bit so will investigate. I'm pretty sure it should be possible though

@bzbetty
bzbetty commented Dec 18, 2015

it works but it requires both the invoice description and client name to
contain all the search terms, I was wanting to be able to do one or the
other. Unfortunately i suspect that would require large changes.

On Fri, Dec 18, 2015 at 9:10 PM, John Nye notifications@github.com wrote:

Hmmm, I would have thought the first option would have done the trick.
I'll be on the train to work in a bit so will investigate. I'm pretty sure
it should be possible though


Reply to this email directly or view it on GitHub
#4 (comment)
.

@ninjanye
Owner

Ah, I see, apologies. Funnily enough, I have just replied to issue #6 asking for precisely the same thing.

As a workaround, you could potentially run them as 2 separate queries (which I know is not ideal). What this does mean is that you only have to perform the second query if the first doesn't return any results. Something like:

var description = Context.Invoices.Search(invoice => invoice.Description)
                                  .ContainingAll(searchTerms);

var client = Context.Invoices.SearchChildren(invoice => invoice.Client)
                                  .With(client => client.Name)
                                  .ContainingAll(searchTerms)
@bzbetty
bzbetty commented Dec 18, 2015

it's not actually a big deal in my case as normally the user knows which
field contains the data anyway so I've put 2 buttons in the UI. 2
searches + a union of some kind would work fairly well too. Cheers for the
help.

On Fri, Dec 18, 2015 at 10:07 PM, John Nye notifications@github.com wrote:

Ah, I see, apologies. Funnily enough, I have just replied to issue #6
#6 asking for
precisely the same thing.

As a workaround, you could potentially run them as 2 separate queries
(which I know is not ideal). What this does mean is that you only have to
perform the second query if the first doesn't return any results. Something
like:

var description = Context.Invoices.Search(invoice => invoice.Description)
.ContainingAll(searchTerms);

var client = Context.Invoices.SearchChildren(invoice => invoice.Client)

.With(client =>
client.Name).ContainingAll(searchTerms)


Reply to this email directly or view it on GitHub
#4 (comment)
.

@ninjanye
Owner

No probs, I will look at how we can maybe have an indicator in the searches to allow for an OR search across search types as it would clearly be useful since you and @sunflowerlab have both mentioned it.

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