Предполагая, что у меня есть родительский класс, который я фильтрую по различным свойствам, один из которых является свойством, являющимся массивом элементов. Теперь скажите, что я хочу вернуть родительский элемент только в том случае, если мой массив элементов как указано выше значения min и ниже максимального значения ... это нормально, я могу работать, что бит; Что делать, если я тогда хочу затем сортировать по фильтрованной результирующего набора этих элементовФильтр Raven DB на подмножество элементов массива и сортировка по самым дешевым результатам результатов фильтра.
я сделал пример AC# скрипку, чтобы показать, что им пытаются достичь: https://dotnetfiddle.net/mV4d28 (обратите внимание, что foo2 возвращается первым, даже если Foo1 имеет элементы в своем массиве, которые меньше, чем в foo2)
Как мне нужно сделать это с помощью индекса, мне нужен индекс, чтобы иметь возможность вычислять заказ на основе критериев фильтра, используемых в моем запросе.
Я знаю, что у elasticsearch есть внутренняя функция хитов, которая дозирует это, и монго имеет трубопроводы, которые также дозаправляют это, поэтому я уверен, что у Ворона должен быть способ сделать это тоже?
Я надеялся, используя только индекс и преобразование с колясками я мог бы добиться этого, так что я пробовал:
мой индекс и трансформировать внешний вид, как этот
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. Есть ли другой, чтобы достичь того, что я хочу, используя прогнозы или пересечение или ранжирование или уменьшить метод try?
Я думаю, если я должен был, возможно, я мог бы использовать 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();
}
}
затем сделать где фильтр и порядок по п с использованием индекса и преобразование переходящего в том же самом коляски, которые я использую в фильтре где. однако я не уверен, что это сработает? Что еще более важно, я не уверен, как я собираюсь получить сортировку dll в плагинах, т. Е. Какое пространство имен должно пройти под классом, какие пространства имен нужно дозировать, нужно импортировать, какое название названия сборки нужно использовать и т. Д. Согласно https://ravendb.net/docs/article-page/3.5/csharp/server/plugins/what-are-plugins i просто нужно отбросить dll, и ворон сделает это, но я не могу найти, какое пространство имен мне нужно ссылаться на IndexEntriesToComparablesGenerator?
im используя linqpad 5, чтобы проверить мои вещи ...поэтому для того, чтобы использовать пользовательский порядок я должен ссылаться на класс
какие-либо советы или советы или как гильдии/примеры приветствовать
как предупреждение/примечание, используя трансформации для фильтрации ворон, означает, что вы не можете использовать пейджинг. Кажется, что ворон применяет пейджинг после индекса и до преобразования. кажется, что его ограничение ворона не в состоянии делать внутренние хиты, такие как elasticsearch –