Groupings with Find

Vote:
 

I have indexed a bunch of products. Each product has an "area" (e.g. groceries, office,...) and a subarea (e.g. deli, meat, paper, pens). I need to do a query which returns the area/subarea tree for a subset of products.

That is, if e.g. I query for all products in store #1, I want to get:

groceries
  meat
office
  paper
  pens

(because store #1 has no products in the deli subarea).

While store #2 has only food items, hence it would return:

groceries
  deli
  meat

When doing this with linq to a db, I just used groupings. What is the correct way to do this with Find? Facets seem to return only counts, and not associations.

#145222
Feb 29, 2016 15:33
Vote:
 

Use episerver categories? 

In that case you get the facets and getting the associations you can use the category api. 

Or store the paths "groceries/meat" in a separate property that you index as well and do a facet on that one. It's pretty nice to let the index have all information you need so you don't need to do n database calls when displaying lists.

#145226
Feb 29, 2016 17:07
Vote:
 

Thanks for the suggestion.

If I had the static tree at the web server, it would all be very simple: all I'd need is the leaves and I could reconstruct the tree. But the tree is implicitly defined by the product properties. That is, if a Catalog administrator adds a product with area "music" and subarea "classical", this should show up, without the need to compatibly edit a separate area/subarea tree.

#145229
Feb 29, 2016 17:34
Vote:
 

Then add that information to the object that is indexed in a separate property. And use that property to build your tree. If the taxonomy changes, update the indexed items...?

#145232
Feb 29, 2016 20:29
Vote:
 

Sorry, but I don't follow you at all, could you give a concrete example of what you mean?

#145235
Feb 29, 2016 20:49
Vote:
 

You can add fields to an indexed object by using conventions like in

http://world.episerver.com/documentation/Items/Developers-Guide/EPiServer-Find/11/DotNET-Client-API/Customizing-serialization/Including-fields/

Then you can add a field in index to your product that contains the full path like "groceries/meat" so you don't have to look it up in db when it is returned from index. Store everything you need to show relations etc directly on the indexed object.

Makes sense?

#145240
Feb 29, 2016 21:58
Vote:
 

I guess what I'm not seeing is how to do the reduction at the Find end; that is, if I have 80,000 products which all match the search parameters, but they all have the same property/properties (say all are groceries/deli) how do I get back just the one distinct result from Find, rather than getting back 80,000 results and having to do the reduction/grouping at my end?

#145247
Mar 01, 2016 8:02
Vote:
 

Have you seen this thread? http://world.episerver.com/forum/developer-forum/EPiServer-Search/Thread-Container/2016/1/sorting-results-by-quotgroup-byquot-like-function/

#145249
Mar 01, 2016 8:34
Vote:
 

Ok, thanks, I guess I'll do something like that. But I have to say, it seems like a very inelegant way to have to do things. I mean, I have a couple of numeric properties*; I have to mash them together, convert to a string, then re-parse at my end. Why wouldn't Find/Elastic Search provide an easy way to return distinct results?

* for ease of description I presented them as strings above but actually they are numeric IDs

#145250
Mar 01, 2016 8:43
Vote:
 

Yup, first get them into index as an additional field and the use facet to get them grouped on the other side when you fetch then. Yeah building trees of facets could be made easier. It takes a little work as is. 

#145253
Mar 01, 2016 9:17
Vote:
 

Well, as I see it, the problem is not really the tree structure. Let's say all I want is a list of the Areas of the resulting products. Even this seems a bit problematic. "just use facets", but:

Since they are integers, I could try histogram; if they were compact (say 1-100) that would work fine but if they are sparse (depending on the representaion of the histogram) this could be very inefficient.

If I want to treat them as strings to use terms, I thought I could do "...Select(x => new {idstring = x.areaId.tostring()}).TermsForFacet(..." but that won't work, so it's actually necessary to add new fields to the objects I'm indexing, which wastes space and adds significantly to the maintainence of the DB (have to change the code for data entry to include the converted fields, etc.) 

All in all, I find it a bit disappointing that something this common and useful needs this kludgy implementation. I feel like I must be missing something.

#145273
Mar 01, 2016 13:27
Vote:
 

Search indexes are great for collections of items but less so for relations between objects. That's where sql db rules. It's possible to solve without too much code but not as easy as if you were using EF and sql no. The last will be prettier code :)

#145297
Mar 01, 2016 16:15
Vote:
 

I do however notice that Elastic Search does have aggregation; so why doesn't Find? Is there a theoretical reason, or is it just that they haven't added it to the C# api? Is there a way to directly use the elastic search features?

#145361
Mar 02, 2016 13:32
Vote:
 

Facets is a form of aggregation. What was called facets in elastic search has been replaced by aggregate...(Which is more powerful)

Facets are somewhat more limited for nested data like yours true. It would be sweet with support for more than a single level of facets. Shouldn't be too tricky to add to find with a few creative extensions.

I'll add as a feature request...

#145364
Edited, Mar 02, 2016 14:15
Vote:
 

Yes, Elastic Search aggregates seem to do actual grouping (buckets) which I think would be very useful. Thanks.

#145384
Mar 02, 2016 18:27
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.