November Happy Hour will be moved to Thursday December 5th.
November Happy Hour will be moved to Thursday December 5th.
Hi,
You can use the InCriterion of StringCriterion to filter on multiple values, like an SQL IN statement.
Like so:
TopicQuery tq = new TopicQuery();
tq.Subject = new StringCriterion();
tq.Subject.Includes = new StringInCriterion();
tq.Subject.Includes.Values.Add("string1");
tq.Subject.Includes.Values.Add("string2");
MessageCollection result = ForumHandler.GetQueryResult(tq);
I cant get it to work as I want with the souloution above, what I realy want to do is making a query that searches "%word1%" OR "%word2%" OR "%word3%" in both subject and text.
Right now i've got the folowing code:
string[] strSearchWords = Request.QueryString["search"].Trim().Split(' ');
CriteriaGroup criteriaGroup = new CriteriaGroup();
MessageCollection topicCollection = new MessageCollection();
TopicQuery topicQuery = new TopicQuery();
topicQuery.Text = new StringCriterion();
topicQuery.Subject = new StringCriterion();
topicQuery.CreateDate = new DateTimeCriterion();
//Set values to filter on
topicQuery.Text.WildCardType = WildCardType.Both;
topicQuery.Subject.WildCardType = WildCardType.Both;
topicQuery.Subject.Includes = new StringInCriterion();
topicQuery.Text.Includes = new StringInCriterion();
topicQuery.Subject.Includes.Values.AddRange(strSearchWords);
topicQuery.Text.Includes.Values.AddRange(strSearchWords);
//Group Text and subject
criteriaGroup.AddCriterion(topicQuery.Text);
criteriaGroup.AddCriterion(LogicalOperator.Or, topicQuery.Subject);
topicQuery.AddCriteriaGroup(criteriaGroup);
//Order by create date
topicQuery.OrderBy.Add(new CriterionSortOrder(topicQuery.CreateDate, SortingDirection.Descending));
//Get the fitered topic collection
topicCollection = ForumHandler.GetQueryResult(topicQuery);
If I have a topic with the text: Mycket bra forum, I can't get a match if i search with the words Mycket forum, they need to be in the right order to match, witch i want to avoid.
Hi Niklas,
You are correct that wildcards are not possible inside a StringInCriterion, but it is possible to subclass it and override its behavior. In this example I have overriden the default IN (...) statement with a wildcard OR statement. I have also added the possibility to choose which kind of wildcard to use, so there's a little extra code for that also.
// The query execution...
TopicQuery tq = new TopicQuery();
tq.Subject = new StringCriterion();
tq.Subject.Includes = new CustomWildCardStringInCriterion();
tq.Subject.Includes.Values.Add("string1");
tq.Subject.Includes.Values.Add("string2");
// The subclassed InCriterion...
public class CustomWildCardStringInCriterion : StringInCriterion
{
public CustomWildCardStringInCriterion()
{
this.WildCardType = WildCardType.Both;
}
public override string GetQuery(string propertyName)
{
if (Values != null && Values.Count > 0)
{
string parentPropertyName = ((CriterionBase)this.ParentQuery).AssignedPropertyPath;
StringBuilder queryBuilder = new StringBuilder();
queryBuilder.Append("(");
foreach (string val in base.Values)
{
if (queryBuilder.Length > 1)
queryBuilder.AppendFormat(" {0} ", QueryBase.OR_OPERATOR);
queryBuilder.AppendFormat("{0} LIKE {1}", parentPropertyName, this.FormatValue(val));
}
queryBuilder.Append(")");
if (NullValueAction == NullValueAction.Include)
queryBuilder.AppendFormat(" {0} {1} IS NULL", QueryBase.OR_OPERATOR, parentPropertyName);
return queryBuilder.ToString();
}
else
return string.Empty;
}
protected override string FormatValue(string val)
{
return String.Format("'{0}'", GetWildCardValue(val, this.WildCardType).Replace("'", "''"));
}
protected string GetWildCardValue(string val, WildCardType wildCardType)
{
if (wildCardType == WildCardType.None)
return val;
else
{
StringBuilder sb = new StringBuilder();
if (wildCardType == WildCardType.Leading || wildCardType == WildCardType.Both)
sb.Append(QueryBase.PERCENTAGE_OPERATOR);
sb.Append(val);
if (wildCardType == WildCardType.Trailing || wildCardType == WildCardType.Both)
sb.Append(QueryBase.PERCENTAGE_OPERATOR);
return sb.ToString();
}
}
public virtual WildCardType WildCardType
{
get
{
return base.GetParameterValue<WildCardType>("WildCardType");
}
set
{
base.SetParameterValue<WildCardType>("WildCardType", value);
}
}
}
Thanks a bunch Mattias, this seems to work. And as a bonus we got documentation on how to make our own critierions. Happy day!
Hi,
I have a forum where I want to implement a search using StarCommunity.Modules.Forum.Queries. When I want to search the topic.Text and topic.Subject for one word it works great, but when I have an array of words i cant get it to work without making more than one GetQueryResult, witch erases the possibility of using paging.
Is there any solution for this?