2016-12-23 12 views
0

여러 속성 중 하나를 필터링하는 상위 클래스가 있다고 가정합니다. 그 중 하나는 항목의 배열 인 속성입니다. 이제 위의 최소값과 최대 값 미만의 항목 배열에 부모 항목 만 반환하려는 경우 ... 괜찮습니다. 무엇 난 다음 원하는 경우에 다음 종류의 내가 달성하기 위해 노력하고 무엇 메신저 보여 교류 # 바이올린 예제를 만들어배열 항목의 하위 집합에있는 Raven DB 필터와 가장 저렴한 필터 결과 항목 정렬

해당 항목의 필터링 된 결과 집합에 : 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(); 
    } 
} 

다음 할을 경우 같은 전달 필터 순서 인덱스를 사용 by 절 및 변환 내가 어디 필터에 사용하는 유모차. 그러나 이것이 효과가 있을지 확실하지 않은 경우? 더 중요한 것은 메신저 dll을 플러그인으로 가져 오는 방법에 대해 확신하지 못합니다. 예를 들어 어떤 이름 공간이 클래스 아래로 가야하는지, 어떤 이름 공간을 가져와야하는지, 어떤 어셈블리 이름을 사용해야하는지 등 https://ravendb.net/docs/article-page/3.5/csharp/server/plugins/what-are-plugins에 따르면 그냥 dll을 떨어 뜨릴 필요가 있고 까마귀가 이걸 할거야,하지만 내가 할 수없는 이름 공간을 내가 IndexEntriesToComparablesGenerator에 대한 참조해야 찾을 수있을 것 같아?

내 물건을 테스트하기 위해 linqpad 5를 사용 중입니다 ...그래서 사용자 지정 순서를 사용하기 위해 내가 클래스를

어떤 조언 조언이나를 참조 할 필요/예

답변

0

이 그래서 내가 변환에서 필터링을 할 수 있다는 것을 나에게 발생하지 않았다 환영 길드하는 방법 나는이에 대한 크레딧을하지 못할

http://live-test.ravendb.net/databases/altha/indexes/familyIndex?start=0&pageSize=25&resultsTransformer=familyTransfrom&tp-FilterMinValue=3&tp-FilterMaxValue=4

:

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 { 
      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()  
     } into r 
     where r.ChildItemValuesFiltered.Length > 0 
     orderby r.ChildItemValuesFiltered.Min() 
     select r; 

내가 여기에, 원하는 샘플 쿼리 무엇인지 저를 준다 까마귀들에게 도움이되었지만 다른 사람들을 위해 지식을 공유했기 때문에 경고/쪽지와 마찬가지로

+0

과 같이 레이븐에서 걸러 내기 위해 변형을 사용하면 페이징을 사용할 수 없다는 것을 의미합니다. 레이븐은 색인 뒤에서 변환하기 전에 페이징을 적용하는 것 같습니다. 그것의 까마귀의 한계가 elasticsearch 같이 안 안타를 할 수 있지 않는 것을 보인다 –