9

We are implementing keyword based retrieval of the content. When querying the broker for components tagged with ANY of the given keywords in a Taxonomy, results returned are not sorted by relevance.

If the query is for any of the 3 keywords, I would like to have the results in the following order.

  1. Content tagged with all 3 given keywords and not tagged with any other keywords
  2. Content tagged with all 3 given keywords and also tagged with other keywords
  3. Content tagged with with 2 given keywords and not tagged with any other keywords
  4. Content tagged with 2 given keywords and also tagged with other keywords
  5. Content tagged with 1 given keyword and not tagged with any other keywords
  6. Content tagged with 1 given keyword and but also tagged with other keywords

When returned in this order, consumers of the content will have the best matched results at the top.

How can I get the results sorted in this order using CD APIs?

0

1 Answer 1

2

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:

  1. 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;
    }
  1. Same kind of lists with 2 keywords ((use same method with some modifications) Only have to use InCriteria with two keyword ids (either or)-

  2. 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 !!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.