4

Advanced.LuceneQueryを使用しています。例:

RavenQueryStatistics stats = null;
vm.Products = DocumentSession.Advanced.LuceneQuery<Product>("Products/Index")
            .Statistics(out stats)
            .Where(searchExpression)
            .OrderBy(columnToSortBy)
            .Skip((vm.PageIndex - 1) * vm.PageSize)
            .Take(vm.PageSize)
            .ToArray()
            ;

このインデックスで

public Products_Index()
{
    Map = products => from p in products
                      select new
                      {
                          p.ItemNum,
                          p.BrandName,
                          p.ProductName,
                          p.Catalog,
                          p.UOM,
                          p.CasePack,
                          p.AveWeight,
                          p.CatalogId,
                          p.HasPicture,
                          p.INFO2,
                          p.IsOfflineSupplierItem,
                          p.IsRebateItem,
                          p.IsSpecialOrderItem,
                          p.IsSpecialPriceItem,
                          p.Price
                      };

    Indexes.Add(x => x.INFO2, FieldIndexing.Analyzed);
    Indexes.Add(x => x.CatalogId, FieldIndexing.Analyzed);
    Indexes.Add(x => x.HasPicture, FieldIndexing.Analyzed);
    Indexes.Add(x => x.IsOfflineSupplierItem, FieldIndexing.Analyzed);
    Indexes.Add(x => x.IsRebateItem, FieldIndexing.Analyzed);
    Indexes.Add(x => x.IsSpecialOrderItem, FieldIndexing.Analyzed);
    Indexes.Add(x => x.IsSpecialPriceItem, FieldIndexing.Analyzed);
    Indexes.Add(x => x.Price, FieldIndexing.Analyzed);
}

実行する典型的な式は次のようになります

"INFO2:(blue*) AND INFO2:(pen*) AND HasPicture:(True) AND IsSpecialOrderItem:(True) AND IsRebateItem:(True) AND IsOfflineSupplierItem:(True) AND CatalogId:(736275001)" 

次に、価格列/インデックスに基づく範囲検索を組み込む必要があります。where句のその部分を構成する構文は何でしょうか?

要件は次のとおりです

価格>=FromNumber価格<=ToNumber

編集:where句を構成するメソッド

private void ProductSearch(ProductSearchViewModel vm)
{

    var terms = vm.SearchTerm
        .ToLower()
        .Split(new char[] { ' ' });

    // Start buildeing up the query
    var sb = new StringBuilder();

    // terms
    foreach (string term in terms)
    {
        sb.AppendFormat("INFO2:({0}*) AND ", term);
    }

    if (vm.Filters != null)
    {

        // picture 
        if (vm.Filters.IsAtrFilterPictureSelected)
        {
            sb.AppendFormat("HasPicture:({0}) AND ", vm.Filters.IsAtrFilterPictureSelected);
        }
        // special order
        if (vm.Filters.IsAtrFilterSpecialOrderSelected)
        {
            sb.AppendFormat("IsSpecialOrderItem:({0}) AND ", vm.Filters.IsAtrFilterSpecialOrderSelected);
        }
        // special price
        if (vm.Filters.IsAtrFilterSpecialPriceSelected)
        {
            sb.AppendFormat("IsSpecialPriceItem:({0}) AND ", vm.Filters.IsAtrFilterSpecialPriceSelected);
        }
        // rebate
        if (vm.Filters.IsAtrFilterRebateSelected)
        {
            sb.AppendFormat("IsRebateItem:({0}) AND ", vm.Filters.IsAtrFilterRebateSelected);
        }
        // offline supplier
        if (vm.Filters.IsAtrFilterOfflineItemSelected)
        {
            sb.AppendFormat("IsOfflineSupplierItem:({0}) AND ", vm.Filters.IsAtrFilterOfflineItemSelected);
        }
        // catalog
        if (vm.Filters.CatalogSelected > 0)
        {
            sb.AppendFormat("CatalogId:({0}) AND ", vm.Filters.CatalogSelected);
        }
        // price range
        if (vm.Filters.PriceFrom > 0 && vm.Filters.PriceTo > 0)
        {
            sb.AppendFormat("Price_Range:[{0} TO {1}]", NumberUtil.NumberToString((double)vm.Filters.PriceFrom), NumberUtil.NumberToString((double)vm.Filters.PriceTo));
        }

    }

    // remove the last 'AND' from the string 
    var searchExpression = sb.ToString();
    if (searchExpression.EndsWith("AND "))
    {
        searchExpression = searchExpression.Substring(0, searchExpression.LastIndexOf("AND "));
    }

    // trace it out
    Logger.WriteMessage(Infrastructure.Logging.LogLevel.Info, "Search Term: " + searchExpression);

    Stopwatch watch = Stopwatch.StartNew();

    string columnToSortBy = string.Empty;
    if (vm.GridParams != null)
    {
        // Luncene specific way of ordering
        columnToSortBy = vm.GridParams.sidx ?? "Price";
        columnToSortBy = vm.GridParams.sord == "asc" ? "+" + columnToSortBy : "-" + columnToSortBy;
    }

    // execution of query
    RavenQueryStatistics stats = null;
    vm.Products = DocumentSession.Advanced.LuceneQuery<Product>("Products/Index")
                .Statistics(out stats)
                .Where(searchExpression)
                .OrderBy(columnToSortBy)
                .Skip((vm.PageIndex - 1) * vm.PageSize)
                .Take(vm.PageSize)
                .ToArray()
                ;

    watch.Stop();
    vm.TotalResults = stats.TotalResults;
    Logger.WriteMessage(Infrastructure.Logging.LogLevel.Info, "Search Time: " + watch.ElapsedMilliseconds);

}

ありがとう、スティーブン

4

2 に答える 2

6

次のようなものが必要です(「_Range」に注意してください)。

Price_Range:[FromNumber TO ToNumber]

詳細については、Luceneクエリ構文のドキュメントを参照してください。また、数値を正しい16進形式で入力する必要があります。自分で行うのではなく、Raven.Abstractions名前空間のNumberUtilsクラスの組み込み関数を使用してこれを行うようにしてください。

しかし、低レベルのLucene APIを使用して、手動でクエリを作成している理由はありますか?LINQをサポートする強く型付けされたAPIがあり、多くの作業を実行します(session.Query<T>())。

于 2012-04-10T22:09:54.207 に答える
5

マットのコメントを繰り返します。手作業でクエリを作成することは本当に避けたいと思います。Lucene Query APIには、WhereBetweenというメソッドがあります。パラメータのフォーマットなど、本当に考慮したいことを行うために、そこにはたくさんの魔法が起こっていることに注意してください。

于 2012-04-11T05:43:26.627 に答える