Umbraco 检查,嵌套多个布尔运算符
Umbraco Examine, nested multiple boolean operators
我正在尝试将这些过滤器添加到一个已经合理的复杂 Umbraco Examine 查询中,并且发现您不能将 API 与原始 lucene 查询混合使用,因此可能必须完成整个过程raw,我试图避免这种情况,因为它是一个具有相当多维度的查询构建器。
API 可以实现这种事情吗?我看到了 GroupedOr/And
但我看不出它是如何削减的,因为这些是 exclusive/inclusive sql "In" 类型的查询。
AND ((_nodeTypAlias: 'Event' AND eventDate:(0xx TO 0xx)) OR (NOT _nodeTypAlias: 'Event'))
AND ((_nodeTypAlias: 'Article' AND postDate:(0xx TO 0xx)) OR (NOT _nodeTypAlias: 'Article'))
以最优秀的成绩做到了Lucence query builder API
var q = new QueryBuilder()
.Must
.MatchSubQuery(and => and
.Should
.MatchSubQuery(qq => qq
.Must
.MatchTerm("__NodeTypAlias", "Event")
.MatchRange(
"comparableEventDate",
DateTime.Now.ToString("yyyyMMddHHmm00000"),
DateTime.Now.AddYears(100).ToString("yyyyMMddHHmm00000"))
.MatchSubQuery(qq => qq
.MustNot
.MatchTerm("__NodeTypAlias", "Event"))
)
.Query
.ToString();
输出:
+((+__NodeTypAlias:Event +eventDate:[42920 TO 79444]) (-__NodeTypAlias:Event))
并将其传递给 Umbraco 检查:
ISearchCriteria criteria = searcher.CreateSearchCriteria();
var filter = criteria.RawQuery(q);
var results = searcher.Search(filter, MaxResults);
Should
运算符转换为 "OR" 而 Must
转换为 AND(Lucene 命名法)。
作为参考,您还需要在收集节点数据时将新的可比较日期字段写入索引:
private void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e, UmbracoHelper umbraco)
{
if (e.IndexType != IndexTypes.Content) return;
try
{
var content = new Node(e.NodeId);
if (e.Fields.ContainsKey("postDate"))
e.Fields.Add("comparablePostDate", DateTime.Parse(e.Fields["postDate"]).ToString("yyyyMMddHHmm00000"));
if (e.Fields.ContainsKey("eventDate"))
e.Fields.Add("comparableEventDate", DateTime.Parse(e.Fields["eventDate"]).ToString("yyyyMMddHHmm00000"));
AddAuthor(e.Fields, content);
}
catch (Exception ex)
{
LogHelper.Error(this.GetType(), "Error in Umbers custom ExamineEvents_GatheringNodeData: ", ex);
//does nowt!
throw;
}
}
我正在尝试将这些过滤器添加到一个已经合理的复杂 Umbraco Examine 查询中,并且发现您不能将 API 与原始 lucene 查询混合使用,因此可能必须完成整个过程raw,我试图避免这种情况,因为它是一个具有相当多维度的查询构建器。
API 可以实现这种事情吗?我看到了 GroupedOr/And
但我看不出它是如何削减的,因为这些是 exclusive/inclusive sql "In" 类型的查询。
AND ((_nodeTypAlias: 'Event' AND eventDate:(0xx TO 0xx)) OR (NOT _nodeTypAlias: 'Event'))
AND ((_nodeTypAlias: 'Article' AND postDate:(0xx TO 0xx)) OR (NOT _nodeTypAlias: 'Article'))
以最优秀的成绩做到了Lucence query builder API
var q = new QueryBuilder()
.Must
.MatchSubQuery(and => and
.Should
.MatchSubQuery(qq => qq
.Must
.MatchTerm("__NodeTypAlias", "Event")
.MatchRange(
"comparableEventDate",
DateTime.Now.ToString("yyyyMMddHHmm00000"),
DateTime.Now.AddYears(100).ToString("yyyyMMddHHmm00000"))
.MatchSubQuery(qq => qq
.MustNot
.MatchTerm("__NodeTypAlias", "Event"))
)
.Query
.ToString();
输出:
+((+__NodeTypAlias:Event +eventDate:[42920 TO 79444]) (-__NodeTypAlias:Event))
并将其传递给 Umbraco 检查:
ISearchCriteria criteria = searcher.CreateSearchCriteria();
var filter = criteria.RawQuery(q);
var results = searcher.Search(filter, MaxResults);
Should
运算符转换为 "OR" 而 Must
转换为 AND(Lucene 命名法)。
作为参考,您还需要在收集节点数据时将新的可比较日期字段写入索引:
private void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e, UmbracoHelper umbraco)
{
if (e.IndexType != IndexTypes.Content) return;
try
{
var content = new Node(e.NodeId);
if (e.Fields.ContainsKey("postDate"))
e.Fields.Add("comparablePostDate", DateTime.Parse(e.Fields["postDate"]).ToString("yyyyMMddHHmm00000"));
if (e.Fields.ContainsKey("eventDate"))
e.Fields.Add("comparableEventDate", DateTime.Parse(e.Fields["eventDate"]).ToString("yyyyMMddHHmm00000"));
AddAuthor(e.Fields, content);
}
catch (Exception ex)
{
LogHelper.Error(this.GetType(), "Error in Umbers custom ExamineEvents_GatheringNodeData: ", ex);
//does nowt!
throw;
}
}