Here is my catalog structure
Below is my query, I want to filter all products under Category A, however I get empty results. Can someone tell me if the query has any problem?
var products = SearchClient.Instance.Search()
.Filter(x => (_contentLoader.Get(x.ParentLink).ParentLink.ID.Match(Category A.ID)))
It's something like.Filter(x=>x.Ancestors().Match(rootId))
where rootId is your Category A
Edit: Use Ancestors as Daniel says :-)
You cannot do querying in Find as you would do in Linq. The Filtering you are doing is being done against fields that resides in the index. You could add this either as a new property on your object, or as an extension method. If you add an extension method, it would be something like:
public static int MyCustomField(this ProductContent content)
// add logic to fetch the ID here
and then you need to make sure this extension method is being included when indexing:
SearchClient.Instance.Conventions.ForInstancesOf<ProductContent>().IncludeField(x => x.MyExtraField());
Finally, you'll need to reindex, and then you can use the filter:
.Filter(x => x.MyExtraField().Match(.....))
"Ancestors" is already included in the index by conventions, which is why you do filtering on it.
Extra extra Tip: Use Find's explore view to inspect the index. If the value you need to filter on is not there, you cannot filter on it.
It works like a charm!!
Just for curiosity, why my query does not work? I have check parent IDs, there is one matched the current category ID.
Thanks for such great details. It's very frustrating to figure out how it works initially. I really appreciate for you all help.
If EPiServer Find has a way like 'luke' to analyse the luncene index, it will simplify the things a lot.
Can anyone help to answer this thread?
I've made a plugin which makes it easier to inspect items in the index, but that is for IContent only (have not tried with commerce data though!). You could give it a go:
After successfully include the custom property, how can I retrieve this from the index instead of getting from the episerver api?
I found a solution from another thread
and changed extension method to public getter property, it seems working. :)
I'm not sure what you mean. When invoking an extension method inside of a .Filter statement, the value will be fetched from the index. The logic that actually resides in the extension method will not be invoked - that only happens when doing the indexing. Try for yourself: Use an extension method and start a debugging sessions. If you set a breakpoint withing the extension method you'll see that it won't get hit when doing querying - only when indexing.The Find API will only look at the name and type of the extension method, and then use that information to look for a matching field in the index.
When I debug it in the morning, I saw it invoked the extension method while iterating the search result. Maybe I'm too tired, I will give another try later.
When interating the search results it will invoke, as you have already executed the query.
What I mean is since the new properties are already stored in the index, why does it need to call the extension method again while enumerating the results?
If you need to use the new values in the search results, and not just while filtering, you might want to create them as properties instead, or create poco's and use projections instead.