我正在使用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子句的那一部分的语法是什么?
要求是
价格&gt; = FromNumber 价格&lt; = 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);
}
谢谢你, 斯蒂芬
答案 0 :(得分:6)
你需要这样的东西(注意“_Range”):
Price_Range:[FromNumber TO ToNumber]
有关完整信息,请参阅Lucene query syntax文档。您还需要将数字设置为正确的十六进制格式。确保使用Raven.Abstractions命名空间中NumberUtils class中的内置函数为您执行此操作,而不是自己执行此操作。
但是是否有理由使用低级Lucene API并手动构建查询?有一个带有LINQ支持的强类型API,可以为你做很多工作(session.Query<T>()
)。
答案 1 :(得分:5)
重申马特的评论。你真的想避免手工构建查询。 Lucene Query API有一个方法,WhereBetween可以为您完成所有操作。 请注意,那里有很多魔法,比如参数格式化等,你真的想要考虑它们。