我有两个相关的问题。
第一: 我正在寻找针对Dynamics CRM 4.0中的自定义实体的全文搜索。有没有人以前做过这个或知道怎么做?
我知道我可以使用Web服务和sdk构建QueryExpressions,但是我可以使用此方法使用布尔类型语法进行全文搜索吗?据我所知,这不会成功。
第二: 有没有其他人对Dynamics CRM 4.0提供的搜索功能感到受限?我知道有一些第三部分的搜索产品,但我还没找到我喜欢的产品。任何建议将不胜感激。
答案 0 :(得分:4)
通过CRM SDK进行搜索和过滤确实需要一些时间来习惯。为了模拟全文搜索,您需要使用嵌套的FilterExpressions作为QueryExpression.Criteria。 SDK page for nested filters最困难的部分是弄清楚如何建立父子关系。有很多布尔逻辑,很容易迷失。
我要求为我们的一个自定义实体构建“搜索引擎”。将此方法用于具有多个可搜索属性的复杂搜索字符串(“一个AND两个或三个”)是很难看的。如果您对此感兴趣,我可以将其挖掘出来。虽然它不是真的支持,但如果你可以直接访问数据库,我建议使用SQL的全文搜索功能。
- 好的,你走了。我认为你不能复制粘贴这个并满足你的需求。我的客户只进行了两到三次关键词搜索,他们对此结果非常满意。您可以看到在简单的搜索方案中执行此操作会带来多大的痛苦。我基本上把代码写出来,直到它“工作”。
private FilterExpression BuildFilterV2(string[] words, string[] seachAttributes)
{
FilterExpression filter = new FilterExpression();
List<FilterExpression> allchildfilters = new List<FilterExpression>();
List<string> andbucket = new List<string>();
List<string> orBucket = new List<string>();
// clean up commas, quotes, etc
words = ScrubWords(words);
int index = 0;
while (index < words.Length)
{
// if current word is 'and' then add the next wrod to the ad bucket
if (words[index].ToLower() == "and")
{
andbucket.Add(words[index + 1]);
index += 2;
}
else
{
if (andbucket.Count > 0)
{
List<FilterExpression> filters = new List<FilterExpression>();
foreach (string s in andbucket)
{
filters.Add(BuildSingleWordFilter(s, seachAttributes));
}
// send existing and bucket to condition builder
FilterExpression childFilter = new FilterExpression();
childFilter.FilterOperator = LogicalOperator.And;
childFilter.Filters = filters.ToArray();
// add to child filter list
allchildfilters.Add(childFilter);
//new 'and' bucket
andbucket = new List<string>();
}
if (index + 1 < words.Length && words[index + 1].ToLower() == "and")
{
andbucket.Add(words[index]);
if (index + 2 <= words.Length)
{
andbucket.Add(words[index + 2]);
}
index += 3;
}
else
{
orBucket.Add(words[index]);
index++;
}
}
}
if (andbucket.Count > 0)
{
List<FilterExpression> filters = new List<FilterExpression>();
foreach (string s in andbucket)
{
filters.Add(BuildSingleWordFilter(s, seachAttributes));
}
// send existing and bucket to condition builder
FilterExpression childFilter = new FilterExpression();
childFilter.FilterOperator = LogicalOperator.And;
childFilter.Filters = filters.ToArray();
// add to child filter list
allchildfilters.Add(childFilter);
//new 'and' bucket
andbucket = new List<string>();
}
if (orBucket.Count > 0)
{
filter.Conditions = BuildConditions(orBucket.ToArray(), seachAttributes);
}
filter.FilterOperator = LogicalOperator.Or;
filter.Filters = allchildfilters.ToArray();
return filter;
}
private FilterExpression BuildSingleWordFilter(string word, string[] seachAttributes)
{
List<ConditionExpression> conditions = new List<ConditionExpression>();
foreach (string attr in seachAttributes)
{
ConditionExpression expr = new ConditionExpression();
expr.AttributeName = attr;
expr.Operator = ConditionOperator.Like;
expr.Values = new string[] { "%" + word + "%" };
conditions.Add(expr);
}
FilterExpression filter = new FilterExpression();
filter.FilterOperator = LogicalOperator.Or;
filter.Conditions = conditions.ToArray();
return filter;
}
private ConditionExpression[] BuildConditions(string[] words, string[] seachAttributes)
{
List<ConditionExpression> conditions = new List<ConditionExpression>();
foreach (string s in words)
{
foreach (string attr in seachAttributes)
{
ConditionExpression expr = new ConditionExpression();
expr.AttributeName = attr;
expr.Operator = ConditionOperator.Like;
expr.Values = new string[] { "%" + s + "%" };
conditions.Add(expr);
}
}
return conditions.ToArray();
}
答案 1 :(得分:1)
您当然可以执行“赞”查询,并将“或”与搜索中包含的列/属性条件放在一起。这似乎是CRM如何从实体列表上方的框中进行查询(并且它们非常快)。看起来CRM数据库有一个全文索引,虽然在短暂的浏览后,我用它来填充它对我来说有点模糊。
请记住LinqtoCRM用于CRM查询爱情(我启动了项目,对无耻的插件感到抱歉)。
答案 2 :(得分:1)
第二 - 我可以推荐Akvelon的“全局搜索”,它提供搜索所有自定义实体和属性以及Out of Box实体和属性的功能。他们还使用FTS在附加的文件内容中进行搜索。您可以在其官方网站上找到更多详细信息:http://www.akvelon.com/Products/Dynamics%20CRM%20global%20Search/default.aspx
答案 3 :(得分:0)
我建议使用在数据库中为您提供的Dynamics CRM过滤视图。然后,您可以利用本机SQL的所有功能来执行您需要的任何LIKE或其他逻辑。此外,过滤后的视图会进行安全修整,因此您无需担心用户访问他们无权访问的记录。