I am not sure if you can get the sorted list from broker the way you want and it seems you may need to put your own customization here. We had a scenario kind of this, I have modified the code for your case to be satisfied, check if this helps.
What you can do as a work around, you can have three (rather 6) separate lists of components retrieved from broker which gives you the following:
- Components with 3 keywords of two types:
List with only 3 keywords , List with 3 and other keywords
Refer to the below code reference for this, may need to do some modifications.
public static Dictionary<string, List<IComponent>> GetComponetsSortedWithKeywords(string tcmid1, string tcmid2, string tcmid3)
{
var resultLists = new Dictionary<string, List<IComponent>>();
ComponentFactory cpf = new ComponentFactory();
List<IComponent> componentListMaxKeyword = new List<IComponent>();
List<IComponent> componentListMinKeyword = new List<IComponent>();
//Check if resultLists exist in cache, load it from here, will improve performance
try
{
//Create query
Query myQuery = new Query();
String taxonomyURI = "tcmid of the taxomomy"; //if keywords are from diff taxonomies provide other taxnomy ids
// Criteria for keywords
List<string> kewordIDList = new List<string>() { tcmid1, tcmid2, tcmid3 };
Criteria keywordOneCriteria = new TaxonomyKeywordCriteria(taxonomyURI, tcmid1, false);
Criteria keywordTwoCriteria = new TaxonomyKeywordCriteria(taxonomyURI, tcmid2, false);
Criteria keywordThreeCriteria = new TaxonomyKeywordCriteria(taxonomyURI, tcmid3, false);
ItemTypeCriteria itemTypeCriteria = new ItemTypeCriteria(16);
int pubid = 0;//your pub id
PublicationCriteria basedOnPublication = new PublicationCriteria(pubid);
// Combine with InCriteria to find all items which have either of the keywords
// Criteria criteria = CriteriaFactory.And(new Criteria[] { keywordOneCriteria, keywordTwoCriteria, keywordThreeCriteria, itemTypeCriteria, basedOnPublication });
Criteria criteria = CriteriaFactory.And(new Criteria[] { keywordOneCriteria, itemTypeCriteria, basedOnPublication });
myQuery.Criteria = criteria;
//Condition for latest published item for multiple returns, which will be available for all copms
SortParameter sortParameter = new SortParameter(
SortParameter.ItemLastPublishedDate,
SortParameter.Descending);
myQuery.AddSorting(sortParameter);
//Executes Query on DB
var results = myQuery.ExecuteQuery().ToList();
//Now apply custom sorting on the results retrieved, hope your components are published
if (results != null && results.Count > 0)
{
foreach (string tcmId in results)
{
Component comp = (Component)cpf.GetComponent(tcmId);
//check component is null or not, hope your components are published
if (comp.Categories.Count > 0)
{
foreach (DD4T.ContentModel.Category category in comp.Categories)
{
if (category.Keywords.Count > 0)
{
List<Keyword> keyWords = category.Keywords;
if (keyWords.Count > kewordIDList.Count)
{
//components associated with more than the specifed three kewords
componentListMaxKeyword.Add(comp);
}
else if (keyWords.Count == kewordIDList.Count)
{
//components associated with the specifed three kewords only
componentListMinKeyword.Add(comp);
}
}
}
}
}
}
}
catch (Exception uiEx)
{
}
//add list to cache,better performance : resultLists
if (componentListMinKeyword != null)
{
resultLists.Add("ComponentWithThreeKeywordOnly", componentListMinKeyword);
}
if (componentListMinKeyword != null)
{
resultLists.Add("ComponentWithMoreThanThreeKeywordOnly", componentListMaxKeyword);
}
return resultLists;
}
Same kind of lists with 2 keywords ((use same method with some modifications)
Only have to use InCriteria with two keyword ids (either or)-
Same kind of lists with 1 keyword (use same method with some modifications)
Now, for getting the sorted list, you may have one predefined object (mapper class sort of), which will map your list objects in a sorted object you want. It also seems you can put some caching logic in place just to improve the performance. Refer to this link for standard caching implementation.
You can try something like below:
If Dictionary object has a key “ComponentWithThreeKeywordOnly” and value is not null, make it as the first item in your list (final list) and this way push the list objects one by one in order.
This is a large scenario, so it would be better if you can try out some options and then if you need help somewhere, you can ask in the forum and you can get more help !!
Let me know if this helps !!