2016-06-30 3 views
3

Учитывая следующий Pocos:ElasticSearch NEST запросов по нескольким типам

public class Dog 
{ 
    public string Name { get; set; } 
} 

public class Cat 
{ 
    public string Name { get; set; } 
    public bool Enabled { get; set; } 
} 

Я хотел бы выполнить запрос, который возвращает все собаки и кошки только что ВКЛЮЧЕНО.

Эластичные документы предоставляют следующий пример, но не какой-либо детали о том, как использовать Bool с запросом или фильтра контекста для поиска конкретных значений поля по нескольким типам:

.Search<object>(s => s 
    .Size(100) 
    .Type(Types.Type(typeof(Dog), typeof(Cat)))     
    .Query(...) 

Как выполнить мой запрос? , Заранее спасибо

+0

Есть ли способ применить фильтрацию только для определенного типа? – LMK

ответ

2

Мы можем запросить поле метаданных _type и объединить это с запросами в других полях. Вот пример. Мы создадим 100 кошек и 100 собак, устанавливая каждые даже кошкам быть отключены

void Main() 
{ 
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    var defaultIndex = "pets"; 
    var connectionSettings = new ConnectionSettings(pool) 
      .DefaultIndex(defaultIndex); 

    var client = new ElasticClient(connectionSettings); 

    if (client.IndexExists(defaultIndex).Exists) 
     client.DeleteIndex(defaultIndex); 

    client.CreateIndex(defaultIndex, ci => ci 
     .Mappings(m => m 
      .Map<Dog>(d => d.AutoMap()) 
      .Map<Cat>(c => c.AutoMap()) 
     ) 
    ); 

    var dogs = Enumerable.Range(1, 100).Select(i => new Dog 
    { 
     Name = $"Dog {i}" 
    }); 

    client.IndexMany(dogs); 

    var cats = Enumerable.Range(1, 100).Select(i => new Cat 
    { 
     Name = $"Cat {i}", 
     Enabled = i % 2 == 0 ? false : true 
    }); 

    client.IndexMany(cats); 
    client.Refresh(defaultIndex); 

    client.Search<object>(s => s 
     .Size(100) 
     .SearchType(SearchType.Count) 
     .Type(Types.Type(typeof(Dog), typeof(Cat))) 
     .Query(q => 
      (+q.Term("_type", "cat") && +q.Term("enabled", true)) || 
      +q.Term("_type", "dog") 
     ) 
    ); 
} 

Поисковый запрос использует перегрузку операторов; унарный + оператор будет означать, что запрос будет обернут в bool запросе filter и точно так же, && будет обернуть в bool запроса must (или filter в этом случае, как мы также использовать унарный оператор +, чтобы сделать его фильтр), и || будет обертываться в запрос boolshould. В результате выполняется запрос выглядит

{ 
    "size": 100, 
    "query": { 
    "bool": { 
     "should": [ 
     { 
      "bool": { 
      "filter": [ 
       { 
       "term": { 
        "_type": { 
        "value": "cat" 
        } 
       } 
       }, 
       { 
       "term": { 
        "enabled": { 
        "value": true 
        } 
       } 
       } 
      ] 
      } 
     }, 
     { 
      "bool": { 
      "filter": [ 
       { 
       "term": { 
        "_type": { 
        "value": "dog" 
        } 
       } 
       } 
      ] 
      } 
     } 
     ] 
    } 
    } 
} 

, который дает

{ 
    "took" : 3, 
    "timed_out" : false, 
    "_shards" : { 
    "total" : 5, 
    "successful" : 5, 
    "failed" : 0 
    }, 
    "hits" : { 
    "total" : 150, 
    "max_score" : 0.0, 
    "hits" : [ ] 
    } 
} 

Это только счетчик, но если вы посмотрите на документы, было бы все собаки и только кошек, которые разрешены

+0

Есть ли способ применить фильтрацию только по определенному типу? – LMK

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