13

I'm obtaining a list of 5 components from the broker using a simple Query:

Query myQuery = new Query();

Criteria myCriteria = null;
PublicationCriteria pubRelCriteria = new PublicationCriteria(iPublicationID);
ItemSchemaCriteria schemaRelCriteria = new ItemSchemaCriteria(id_schema);
ItemTemplateCriteria templateCriteria = new ItemTemplateCriteria(id_template);

// glue the metadata together
AndCriteria aCriteria = new AndCriteria(schemaRelCriteria, pubRelCriteria);
aCriteria = new AndCriteria(aCriteria, templateCriteria);
myCriteria = aCriteria;
myQuery.Criteria = myCriteria;

//Sort it
CustomMetaKeyColumn customMetaKeyColumnDate = new CustomMetaKeyColumn("Date", MetadataType.DATE);

myQuery.AddSorting(new SortParameter(customMetaKeyColumnDate, SortParameter.Descending));

// Display
String[] itemURI = myQuery.ExecuteQuery();

The problem is that the metadatafield "Date" that I need to use as the sort criteria is not mandatory, then if some component is published with this metadatafield empty, this component is not returned in the query.

Is there some way to return all the components despite the field of the sort criteria is empty?

Thanks!

  • 4
    I've seen this happen if you specify custommeta criteria, but not sorting. I would expect underneath the generated SQL to be a simple ORDER BY clause, which should return even the null elements. Try turning on SQL logging in logback and see what query gets generated. Here is how: tridion.stackexchange.com/a/3448/159 – Nickoli Roussakov Mar 24 '15 at 23:12
  • Did you ever find the answer? – Chris Morgan Dec 22 '15 at 13:40
  • Nope, I thought at last that a sql cross join is the normal functionality in this case. Don't know if this must be considered a bug. – Julián Hernández Dec 23 '15 at 16:33
1

Not sure, if you have already found the answer.

An work around would be not to include the optional field in the search criteria.

    ComponentFactory cpf = new ComponentFactory();
Query query = new Query();

//16 for component, 32 for CTs, 64 for Page, here we are dealing with type 16 i.e. components only
ItemTypeCriteria componentsOnly = new ItemTypeCriteria(ItemType.Component.GetHashCode());
SchemaTitleCriteria basedOnSchema = new SchemaTitleCriteria(“Schema Name”);
PublicationCriteria basedOnPublication = new PublicationCriteria(pubId); 
//pubId needs to be provided
//Add template criteria if required
Criteria criteria = CriteriaFactory.And(new Criteria[] { componentsOnly, basedOnSchema, basedOnPublication });

//Setting Criteria for the query object, Schema Name, Pub Ids etc
query.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);
query.AddSorting(sortParameter);

//Executes Query on DB
var results = query.ExecuteQuery().ToList();
 List<IComponent> componentList = new List<IComponent>();
//Now apply custom sorting on the results retrieved
if (results != null && results.Count > 0)
{

                    foreach (string tcmId in results)
                    {
                        try
                        {
                            componentList.Add(cpf.GetComponent(tcmId));
                        }
                        catch
                        {
                        }
                    }
}

 var actualComplist = componentList.OrderByDescending(x => x.MetadataFields["Date"].Value); //Assuming Date is your field name

For setting up the criteria for any broker query you can refer here.

Let me know if this helps or how you have solved it !! Thanks !!

  • Thanks, is it already resolved? If yes, can you share how you have done it? – Anupam Baksi Jan 13 '16 at 13:17
  • Not solved. Your work around can do the job. The pity is that the "order by" is done once you have executed the query, not in the query itself. I suppose that the impact in performance is not huge, but should be done in the same query. I don't know how to make this ordering in the same broker query, or if this can't be done in this case. – Julián Hernández Jan 13 '16 at 13:25
  • 2
    Ok, in that case you can implement caching (check from here: for standard caching logic: tridionwithanupam.wordpress.com/category/tridion-caching). Ideas is for first time execute and store the list of components in cache with some custom cache key (use criteria combinations e.g. schema/pub/template ids together), second time you can check and load it from cache if the combination matched. Hope it will help the performance. If i found exactly what you want will post my response here. – Anupam Baksi Jan 13 '16 at 13:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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