Orchard Lucene自定义搜索服务,带有查询分组和数字范围查询

时间:2016-02-24 07:47:23

标签: orchardcms lucene.net orchardcms-1.9

我正在尝试实现自己的自定义SearchService。据我了解

// If I wanted to query "+name:camera +price:[100 TO 150] +location:thailand"
searchBuilder.WithField("name", "camera").ExactMatch().Mandatory();
searchBuilder.WithinRange("price", 100, 150, true, true).Mandatory();
searchBuilder.WithField("location", "thailand").ExactMatch().Mandatory();

这里没问题。但是如何使用分组处理查询(带括号的子句)?

// How do I query "+name:camera +(price:[100 TO 150] cost:[100 TO 150]) +(bundle-price:[100 TO 150] total-price:[100 TO 150])"?
// Since the ISearchBuilder interface doesn't support grouping, the only other way
// I could think of is to use the freestyle ISearchBuilder.Parse() to construct the query.
// However this doesn't return any hits:
searchBuilder.WithField("name", "camera").ExactMatch().Mandatory();
searchBuilder.Parse("price", "[100 TO 150] cost:[100 TO 150]", false).Mandatory();
searchBuilder.Parse("bundle-price", "[100 TO 150] total-price:[100 TO 150]", false).Mandatory();

ISearchBuilder.Parse()没有足够的信息来确定范围的数据类型(无论是intfloat还是double)。看起来Luke也遇到了这个问题,可以使用我认为Lucene.Net不具备的XML Query Parser来规避这个问题:

Lucene numeric range search with LUKE

我在想,如果ISearchBuilder有一个允许我们插入自己的查询的方法

// /src/Orchard/Indexing/ISearchBuider.cs
public interface ISearchBuilder {
    ISearchBuilder WithQuery(Query query);
}

// /src/Orchard.Web/Modules/Lucene/Services/LuceneSearchBuilder.cs
public class LuceneSearchBuilder : ISearchBuilder {
    public ISearchBuilder WithQuery(Query query) {
        CreatePendingClause();
        _query = query;
        return this;
    }
}

public class CustomSearchService {
    public void Search() {
        // construct our own custom queries
        var booleanQuery1 = new BooleanQuery();
        booleanQuery1.Add(NumericRangeQuery.NewDoubleRange("price", 100, 150, true, true), Occur.SHOULD);
        booleanQuery1.Add(NumericRangeQuery.NewDoubleRange("cost", 100, 150, true, true), Occur.SHOULD);

        var booleanQuery2 = new BooleanQuery();
        booleanQuery2.Add(NumericRangeQuery.NewDoubleRange("bundle-price", 100, 150, true, true), Occur.SHOULD);
        booleanQuery2.Add(NumericRangeQuery.NewDoubleRange("total-price", 100, 150, true, true), Occur.SHOULD);

        searchBuilder.WithField("name", "camera").ExactMatch().Mandatory();
        // insert our custom queries into the SearchBuilder using the newly added interface method (ISearchBuilder.WithQuery()) above
        searchBuilder.WithQuery(booleanQuery1).Mandatory();
        searchBuilder.WithQuery(booleanQuery2).Mandatory();
    }
}

然后我们可以构建更复杂和灵活的查询。

更新

之前有人提出过这个问题 https://github.com/OrchardCMS/Orchard/issues/5764

1 个答案:

答案 0 :(得分:-1)

您可能应该将Search API与facet一起使用。以下是完整的演示文稿:https://www.youtube.com/watch?v=7v5qSR4g7E0以及此处的一些注释:http://weblogs.asp.net/bleroy/orchard-harvest-2015-search-api