Can the search results on the member search page be sorted by an ExtendedAttributes or ProfileFields field?
Can the search results on the member search page be sorted by an ExtendedAttributes or ProfileFields field?
Unfortunately there's not a direct option to list by those fields, see User Script API - List. There is limited logic to perform on-page sorting in Velocity, some capacity in Javascript. However on-page sorting would be limited by paging that is based on a different sort order. You could also expose your own widget extension that could collect all the users from the User In Process API and re-sort them by your desired field. Both the aggregation and the re-sort would be potentially costly operations computationally.
There is limited logic to perform on-page sorting in Velocity,
What is this logic?
You could also expose your own widget extension that could collect all the users from the User In Process API and re-sort them by your desired field.
How would I go about this?
I am returning the sorted Users list from my widget extension, but the users are no longer being filtered on the Member Search page. How can I get the filtering working again?
There is not enough information here to answer this because we don't know what you did or how anything was implemented. If the expectation is that you added your own extension to replace a call on that page and it would just work, then that won't be the case.
Hi,
Here's the C# code:
public class MyUsers { public string GetContentIds() { SqlDataAccess sd = new SqlDataAccess(); using (SqlCommand cmd = sd.GetCommand("ibby_Get_Sorted_User_Content_Ids")) { cmd.CommandType = CommandType.StoredProcedure; DataTable dt = sd.Execute(cmd); StringBuilder sb = new StringBuilder(); for (int i = 0; i < dt.Rows.Count; i++) { sb.Append(dt.Rows[i]["ContentId"].ToString()); if (i != dt.Rows.Count - 1) sb.Append(","); } return sb.ToString(); } } public PagedList<Telligent.Evolution.Extensibility.Api.Entities.Version1.User> GetUsers() { UsersListOptions options = new UsersListOptions(); options.ContentIds = GetContentIds(); options.SortBy = "ContentIdsOrder"; return Apis.Get<Users>().List(options); } }
And search.vm
#set($filters = $core_v2_page.GetFormValue('filters')) ## perform search #set($count = 0) #set ($searchListOptions = "%{ Query = $searchQuery, Sort = 'titlesort', PageIndex = $pageIndex, PageSize = $pageSize }") $searchListOptions.Add("Filters", "type::user${filters}") ##set ($searchResults = $core_v2_searchResult.List($searchListOptions)) #set ($searchResults = $!$ibby_v1_UserData.GetUsers()) ## Render Search Results #set ($hasMore = false) #set ($currentPagedQuantity = ($searchResults.PageIndex + 1) * $searchResults.PageSize) #if ($searchResults.TotalCount > $currentPagedQuantity) #set ($hasMore = true) #end #foreach ($user in $searchResults) #beforeall <div class="content-list thumbnail ui-masonry margin-top" id="$core_v2_encoding.HtmlAttributeEncode($core_v2_widget.UniqueId('thumbnails'))" data-columnclass="thumbnail-column"> #each ##set ($user = false) ##foreach ($resultUser in $result.Users) ## #set ($user = $resultUser) ###end
These are 2 completely different methods for getting users so filters are not going to work. You use the users API, the members page is based on search. These methods are not interchangeable.
Realistically, you could just use Apis.Get<ISearchIndexing>().Events, handle the BeforeBulkIndex event for users, stuff a custom field in the document for the value you want to sort by and then modify any call the Apis.Get<ISearchResults> to include your custom sort in the query
community.telligent.com/.../searchindexing-in-process-api-service
How often does the BeforeBulkIndex event get fired in a user's lifecycle? Is it only once? My custom sort field can change quite often, and it might not have a value before the event gets fired. Will that be a problem?
That event gets fired before altered users get changed in the index, which varies by how often the job runs and how many changes need to be processed. You still will have to store this value somehow and read it when the event is fired
I've attempted to write some code for this. Would this work as a widget extension?
public class MyUsers { public Telligent.Evolution.Extensibility.Api.Entities.Version1.SearchResults GetUsers(int pageIndex, int pageSize, string filters, string query) { ISearchResults search = Apis.Get<ISearchResults>(); var searchOptions = new SearchResultsListOptions { PageIndex = pageIndex, PageSize = pageSize, Query = query, Filters = filters }; searchOptions.Sort = "UserSortOrder"; var results = search.List(searchOptions); return results; //Apis.Get<Users>().List(options); } public void BeforeSearchBulkIndexingEventHandler(BeforeBulkIndexingEventArgs e) { SearchIndexDocument d = new SearchIndexDocument(); d.AddField("UserSortOrder", GetSortOrder(d.ContentId)); e.Documents.Append(d); } private string GetSortOrder(Guid contentId) { SqlDataAccess sd = new SqlDataAccess(); using (SqlCommand cmd = sd.GetCommand("ibby_UserSortOrder_Get")) { cmd.CommandType = CommandType.StoredProcedure; cmd.Parameters.AddWithValue("@ContentId", contentId); DataTable dt = sd.Execute(cmd); if (dt.Rows.Count > 0) return dt.Rows[0]["UserSortOrder"].ToString(); else return string.Empty; } } }
You are not longer writing a widget extension. You are writing a plugin and possibly modifying widget code.
To which of the SearchIndexDocument Documents should I add the custom sort field? The first, the last, a specific one, or all of them?
To which of the SearchIndexDocument Documents should I add the custom sort field? The first, the last, a specific one, or all of them?
You would evaluate them to be of the users content type
Here's the code for the Plugin that I've written to handle the BeforeBulkIndex event for users. I've copied the DLL to the website's bin folder, and the JobServer folder. Does it look okay? How would I get the event to fire for all the users so that it would update all the users?
using Telligent.Evolution.Extensibility;
using Telligent.Evolution.Extensibility.Api.Entities.Version1;
using Telligent.Evolution.Extensibility.Api.Version1;
namespace UserData
{
public class UserDataPlugin : Telligent.Evolution.Extensibility.Version1.IPlugin
{
public string Name
{
get { return "UserDataPlugin"; }
}
public string Description
{
get { return "User Data Plugin"; }
}
public void Initialize()
{
Apis.Get<ISearchIndexing>().Events.BeforeBulkIndex += new BeforeSearchBulkIndexingEventHandler(UpdateSortOrder_BeforeBulkIndex);
}
private void UpdateSortOrder_BeforeBulkIndex(BeforeBulkIndexingEventArgs e)
{
UsersGetOptions o = new UsersGetOptions();
var i = Apis.Get<IUsers>();
foreach (SearchIndexDocument d in e.Documents)
{
o.ContentId = d.ContentId;
var u = i.Get(o);
if (u != null)
{
d.AddField("UserSortOrder", u.ExtendedAttributes["SortOrder"].Value);
}
}
}
}
}
Here's where I change the sort order in search.vm. Is this correct?
#set ($searchListOptions = "%{ Query = $searchQuery, Sort = 'UserSortOrder', PageIndex = $pageIndex, PageSize = $pageSize }")
In 11.1+, you can go to Administration > Site > Search, view the Include tab, uncheck "Users", Save, recheck "Users", and Save again. This will reindex users.
Thanks ALL: This is working now. However, I'd like to take it one step further -
How can I sort the user search results by two fields?
Also, how can I exclude some users from being included in the index?
How can I sort the user search results by two fields?
The sort can be specified as "FIELD DIRECTION,FIELD DIRECTION,...' where FIELD is the name of the field to sort on and DIRECTION is 'asc' or 'desc'
Also, how can I exclude some users from being included in the index?
Users can be excluded by disabling the user's "include in search" option in their settings.
Okay, thanks