2016-10-26 2 views
2

Ich habe Typen in meinen Daten, wenn Typ A ist dann muß ich von price1 sortieren und wenn Typ B dann muß ich von price2 sortieren,Conditional Sortierung auf 2 Felder in Elasticsearch Nest

so in C# NEST, wie können wir Abfrage dafür schreiben?

{ 
    "test": { 
    "mappings": { 
     "listings": { 
     "properties": { 
      "productname": { 
      "type": "string" 
      }, 
      "ptype": { 
      "type": "string" 
      }, 
      "price1": { 
      "type": "float" 
      }, 
      "price2": { 
      "type": "float" 
      } 
     } 
     } 
    } 
    } 
} 
+0

Sie haben zwei Arten im Elasticsearch-Index? – Rob

+0

Ich habe ein Feld "List Typ", die entweder A oder B sein kann. – GMD

+0

Können Sie Ihre Index-Mapping und Beispieldokument teilen? – Rob

Antwort

0

Ist etwas wie das, wonach Sie suchen?

_elasticClient.SearchAsync<ListingsModel>(s => s 
    .Type(type) 
    .Sort(o => 
    { 
     if(type == "A") 
      return o.OnField("price1"); 
     else 
      return o.OnField("price2"); 
    }) 
    //rest of query 
0

Das Beste, was ich konnte, war wie dieser etwas tun

class Program 
    { 
     static void Main(string[] args) 
     { 
      var random = new Random(); 
      var uri = new Uri("http://localhost.fiddler:9200"); 
      var indexName = "test_index"; 

      ElasticClient db = new ElasticClient(uri); 

      db.DeleteIndex(indexName); 

      foreach (var item in Enumerable.Range(0, 10).Select(i => new A { Price1 = random.NextDouble() * 1000 })) 
      { 
       db.Index(item, inx => inx.Index(indexName)); 
      } 

      foreach (var item in Enumerable.Range(0, 10).Select(i => new B { Price2 = random.NextDouble() * 1000 })) 
      { 
       db.Index(item, inx => inx.Index(indexName)); 
      } 

      //db.IndexMany(Enumerable.Range(0, 10).Select(i => new A { Price1 = random.NextDouble() * 1000 }), indexName); When using this got nothing back since the query was too fast after index 
      //db.IndexMany(Enumerable.Range(0, 10).Select(i => new B { Price2 = random.NextDouble() * 1000 }), indexName); 

      var data = db.Search<JObject>(q => 
       q.Index(indexName) 
       .Size(20) 
       .Type("") 
       .Sort(s => s.Script(scd => scd 
        .Type("number") 
        .Script(sc => sc 
         //.Inline(@" doc['price1']? doc['price1'] : doc['price2']") if no price1 field in object B then you can use this and no need for TypeIndex 
         .Inline(@"doc['typeIndex'] == 0? doc['price1'] : doc['price2']")// typeIndex must be a number lucene has no string literal support 
         .Lang("expression") 
         ).Order(SortOrder.Descending)))); 


      Console.WriteLine("DONE"); 

      Console.ReadLine(); 
     } 
    } 

    [ElasticsearchType(Name="A")] 
    public class A 
    { 
     [Number] 
     public int TypeIndex { get { return 0; } } 

     [Number] 
     public double Price1 { get; set; } 
    } 

    [ElasticsearchType(Name = "B")] 
    public class B 
    { 
     [Number] 
     public int TypeIndex { get { return 1; } } 

     [Number] 
     public double Price2 { get; set; } 
    } 

Sie es mit groovigen tun könnte, aber ich weiß nicht, wie gut wird es performe. Ausdruck sind standardmäßig aktiviert und verwenden lucene. Ich denke, es ist ein bisschen "hacky", aber die Hoffnung hilft ein wenig.