2016-10-26 1 views
2

У меня есть тип в моих данных, если типа А, то мне нужно сортировать price1 и если тип B, то мне нужно сортировать по price2,Условная Сортировка по 2 полю в Elastic Search Nest

так в C# NEST, как мы можем написать запрос для этого?

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

У вас есть два типа в индексе elasticsearch? – Rob

+0

У меня есть одно поле «Тип списка», который может быть либо A, либо B. – GMD

+0

Можете ли вы поделиться своим картографированием индекса и образцом документа? – Rob

ответ

0

Что-то типа этого, что вы ищете?

_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

Лучшее, что я был в состоянии сделать что-то вроде этого

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; } 
    } 

Вы можете сделать это с заводной, но я не знаю, насколько хорошо будет его performe. выражение включено по умолчанию, и они используют lucene. Я действительно думаю, что это немного «взломанный», но надежда немного помогает.

Смежные вопросы