假設我有一個父類,我過濾各種屬性,其中之一是屬性是一個項目的數組。 現在說,我只想返回父項目,如果我的數組的項目如上面的最小值和最大值以下...這很好,我可以工作一點; 如果我再要,然後排序經過濾的結果集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來測試我的東西...所以爲了使用自定義命令我必須引用類
任何提示或建議或如何公會/例子歡迎
只是作爲一個警告/旁註,使用變換在烏鴉過濾意味着你不能使用分頁。看來,烏鴉在索引之後和變換之前應用分頁。似乎它是烏鴉不能做彈性搜索等內部命中的限制 –