假设我有一个父类,我过滤各种属性,其中之一是属性是一个项目的数组。 现在说,我只想返回父项目,如果我的数组的项目如上面的最小值和最大值以下...这很好,我可以工作一点; 如果我再要,然后排序经过滤的结果集Raven DB过滤器上的数组项的子集和排序上最便宜的过滤器结果项目
我做了一个C#小提琴例子来说明什么即时试图实现这些项目的: https://dotnetfiddle.net/mV4d28 (注意,foo2的第一,即使foo1返回在它的数组中的项目少于foo2中的项目)
因为我需要使用索引来执行此操作,所以我需要该索引能够根据我的查询中使用的筛选条件计算顺序。
我知道elasticsearch有一个内在的命中功能,这种情况下,mongo的管道也是这样的,所以我确信Raven也有办法做到这一点吗?
我只使用指标,希望和推着婴儿车的变换,我可以做到这一点,所以我试了一下:
我的索引和改造这个样子的
public class familyTransfrom : AbstractTransformerCreationTask<ParentItem>
{
public class Result : ParentItem{
public double[] ChildItemValuesFiltered { get; set; }
}
public familyTransfrom(){
TransformResults = parents => from parent in parents
let filterMinValue = Convert.ToDouble(ParameterOrDefault("FilterMinValue", Convert.ToDouble(0)).Value<double>())
let filterMaxValue = Convert.ToDouble(ParameterOrDefault("FilterMaxValue", Convert.ToDouble(9999)).Value<double>())
select new Result{
ParentItemId = parent.ParentItemId,
ParentItemName = parent.ParentItemName,
ParentItemValue = parent.ParentItemValue,
//ChildItemValuesFiltered = parent.ChildItems.Where(p => p.ChildItemValues.Any(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).SelectMany(t => t.ChildItemValues).ToArray<double>(),
ChildItemValuesFiltered = parent.ChildItems.SelectMany(p => p.ChildItemValues.Where(y => Convert.ToDouble(y) >= Convert.ToDouble(filterMinValue) && Convert.ToDouble(y) <= Convert.ToDouble(filterMaxValue))).ToArray<double>(),
ChildItems = Recurse(parent, x => x.ChildItems).Select(y => y).ToArray()
};
}
}
public class familyIndex : AbstractIndexCreationTask<ParentItem>{
public class Result : ParentItem {
public double[] ChildItemValues { get; set; }
}
public familyIndex(){
Map = parents => from parent in parents
select new Result{
ParentItemId = parent.ParentItemId,
ParentItemName = parent.ParentItemName,
ParentItemValue = parent.ParentItemValue,
ChildItemValues = parent.ChildItems.SelectMany(p => p.ChildItemValues.Select(y => y)).ToArray(),
ChildItems = Recurse(parent, x => x.ChildItems).Select(y => y).ToArray()
};
Index("ParentItemId", FieldIndexing.Analyzed);
Index("ParentItemName", FieldIndexing.Analyzed);
Index("ParentItemValue", FieldIndexing.Analyzed);
Index("ChildItemValues", FieldIndexing.Analyzed);
Index("ChildItems", FieldIndexing.Analyzed);
}
}
我的查询如下,(此使用实况乌鸦操场所以这应该只是工作开箱即用它,你想使用它)
using (IDocumentStore store = new DocumentStore { Url = "http://live-test.ravendb.net/", DefaultDatabase = "altha" })
{
store.Initialize();
using (IDocumentSession session = store.OpenSession())
{
if(1 == 2){
//foreach (ParentItem element in data.OfType<ParentItem>()) {
// session.Store((ParentItem)element);
// session.SaveChanges();
//}
new familyIndex().Execute(store);
new familyTransfrom().Execute(store);
}else{
double filterMinValue = 3.0;
double filterMaxValue = 4.0;
var results = session
.Advanced
.DocumentQuery<familyIndex.Result,familyIndex>()
.WhereBetweenOrEqual("ChildItemValues", filterMinValue, filterMaxValue)
.SetResultTransformer<familyTransfrom, familyTransfrom.Result>()
.SetTransformerParameters(new Dictionary<string, RavenJToken> {
{ "FilterMinValue", filterMinValue },
{ "FilterMaxValue", filterMaxValue } })
.OrderBy("ChildItemValues")
.OfType<ParentItem>().ToList();
results.Dump();
}}
}
我发现什么是我不能使用“ChildItemValuesFiltered”从将结果转换为其非索引。所以除非我能通过变换的结果命令?我无法得到这个工作,因为它虽然它正确地过滤它dosnt命令。 是否有另一个实现我想要使用投影或交集或排名或减少尝试方法?
我在想,如果我不得不或许我可以使用https://ravendb.net/docs/article-page/3.5/csharp/indexes/querying/sorting#custom-sorting
,做这样的事情:
public class SortByNumberOfCharactersFromEnd : IndexEntriesToComparablesGenerator
{
private readonly double filterMinValue;
private readonly double filterMinValue;
public SortByNumberOfCharactersFromEnd(IndexQuery indexQuery)
: base(indexQuery)
{
filterMinValue = IndexQuery.TransformerParameters["FilterMinValue"].Value<double>(); // using transformer parameters to pass the length explicitly
filterMaxValue = IndexQuery.TransformerParameters["FilterMaxValue"].Value<double>();
}
public override IComparable Generate(IndexReader reader, int doc)
{
var document = reader.Document(doc);
double[] childItemValues = (double[])document.GetValues("ChildItemValuesFiltered").Select(double.Parse).ToArray(); // this field is stored in index
return childItemValues.Where(x => x >= min && x <= max).Min();
}
}
然后做一个地方滤波器和为了利用指数条款和改造通过在同一prams,我用在哪里过滤器。但我不知道这是否会工作? 更重要的是,我不知道我如何去获取排序dll到插件,即什么名称空间应该类下,什么名称空间剂量它需要导入,它需要使用什么组装名称剂量等 根据https://ravendb.net/docs/article-page/3.5/csharp/server/plugins/what-are-plugins我只需要放入DLL和乌鸦会这个了,但我似乎无法找到我需要引用IndexEntriesToComparablesGenerator什么名称空间?
即时通讯使用linqpad 5来测试我的东西...所以为了使用自定义命令我必须引用类
任何提示或建议或如何公会/例子欢迎
只是作为一个警告/旁注,使用变换在乌鸦过滤意味着你不能使用分页。看来,乌鸦在索引之后和变换之前应用分页。似乎它是乌鸦不能做弹性搜索等内部命中的限制 –