Umbraco-CMS: `ToPublishedSearchResults` doesn't work for members
Which exact Umbraco version are you using? For example: 9.0.1 - don’t just write v9
10.0.1
Bug summary
Currently there is a ToPublishedSearchResults() Examine extension method, which works for Content and Media, but not when querying Members Index.
https://github.com/umbraco/Umbraco-CMS/blob/v10/contrib/src/Umbraco.Infrastructure/Examine/ExamineExtensions.cs#L92
The following does return results, so it would be useful to get the results as IEnumerable<IPublishedContent> similar to when extracting data from MTNP or Member Picker using property value converters.
var results = query.Execute(new QueryOptions(skip, take));
Either using this:
var items = results
.ToPublishedSearchResults(umbracoContext.PublishedSnapshot)
.Select(x => x.Content);
or this, where umbracoContext.PublishedSnapshot.Members is IPublishedMemberCache.
var items = results
.ToPublishedSearchResults(umbracoContext.PublishedSnapshot.Members)
.Select(x => x.Content);
Specifics
No response
Steps to reproduce
Query Examine member index and try get member results using ToPublishedSearchResults() extension method.
Expected result / actual result
No response
About this issue
- Original URL
- State: open
- Created 2 years ago
- Comments: 15 (13 by maintainers)
I don’t think you are following me here.
The problem that exists in v8 is that you do a paged Examine query (which you are doing in your example) and behind the scenes, for each result, individually, it will make a call to the IMemberService.GetById. So if you have a page size of 20, you are making 20 individual service calls which will probably equate to about 50+ DB queries and most of them are expensive.
It’s not about paging, it’s not about Ids, its about the N+1 problem.
No matter what, we are querying members by Examine (i.e. IContentQuery.Search). This returns Examine results, we need to take those results and lookup the real member in the DB because the indexed data will be different in a lot of cases and then transform that member to IPublishedContent. Again, this is what happens in v8. In v9+, you can do the exact same thing but it will be manual with an IMemberManager lookup and then a call to IMemberManager.AsPublishedMember to transform to IPublishedContent.
Moving forward, there just needs to be a method to bulk lookup members in IMemberManager by multiple Ids so we don’t have an N+1 issue just like I mention above.
Yes of course
No, and it will not be possible because indexed values may not be the same as what is stored and you cannot run IPropertyValueConverters here.
Again - behind the scenes this does an N+1 lookup, it will use IMemberService.GetById for each result, this is not good and removed for performance reasons. Even though you are not seeing performance issues, others will. It will depend on the load of that search page (RPS).
I there were a method to bulk fetch members with IMemberManager than it could all work fine. The current problem is having to lookup individual members one at a time (which was how it worked in v8 too). Then you can have an extension method somewhere that does this:
Often we have a paged result (I don’t recall the exact default) but it could of course be increased to I large number, which in that case would perform bad.
Maybe we need a different utility method the deal with member search results either using MemberManager, mapping properties to a dictionary, or a slim entity (I think Id, Key and Name is always available, while additional properties could be mapped to a dictionary).
Alternatively we could write some documentation to cover this and suggestion to convert the member search results to a strongly typed model.
We could of course write our own, but would be great to share the thoughts with the community.