2015-11-26 2 views
1

Мне нужно получить документы из ES, используя клиент NEST с несколькими условиями И/ИЛИ на двух полях.Объединение запросов с использованием bool в Nest Elasticsearch

Мой запрос как:

SELECT * FROM Document WHERE (Year!=2012 && Year!=2013) AND (Format=".pdf" || Format=".prt" || Format=".jpeg") 

ниже мой код:

var qc = new List<QueryContainer>();   
    foreach (var year in years)// years is the list of years that must not be included 
    { 
     qc.Add(Query<Document>.Match(m => m.OnField(p => p.Year).Query(year))); 
    } 

    var qF = new List<QueryContainer>(); 
    foreach (var format in txtDocs)// txtDocs is the list of formats that should be included if available 
    { 
     qF.Add(Query<Document>.Match(m => m.OnField(p => p.Format).Query(format))); 
    } 

    var searchResults = client.Search<Document>(s => s.Index(defaultIndex).From(0).Size(50). 
     Query(
     f => f.Bool(
      b => b 
       .MustNot(qc.ToArray()).Should(qF.ToArray())))); 

Когда я пытаюсь этот код он работает на те годы, которые не должны появляться в результатах, но и для форматов, должен быть выбран пользователем, он не отображает выбранные форматы, хотя они доступны. Я также использовал «must» вместо «should», но тогда он вообще ничего не извлекает.

У кого-нибудь была такая проблема?

ответ

2
public class Test 
{ 
    public int Year { get; set; } 
    [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)] 
    public string Format { get; set; } 
} 

var searchResponse = client.Search<Test>(s => s.Query(q => q 
    .Bool(b => b 
     .MustNot(
      m => m.Term(t => t.OnField(f => f.Year).Value(2012)), 
      m => m.Term(t => t.OnField(f => f.Year).Value(2013)) 
     ) 
     .Should(
      should => should.Term(t => t.OnField(f => f.Format).Value(".pdf")), 
      should => should.Term(t => t.OnField(f => f.Format).Value(".prt")), 
      should => should.Term(t => t.OnField(f => f.Format).Value(".jpeg")) 
     ) 
    ))); 

Надеюсь, это поможет.

+0

Благодаря Роб! Фактически, я искал код, который создает динамический запрос, так как пользователь может выбрать несколько форматов и лет. Итак, наконец, основываясь на вашем ответе, я понял, где я ошибся! поле формата должно быть «Не проанализировано», и тогда мой код, который добавляется как новый ответ, работает хорошо! – Mahsa

0

Вот код для создания динамического запроса:

QueryContainer qYear=null; 
    foreach (var year in years) 
    { 
     qYear |= new TermQuery() { Field = "year", Value = year };  
    } 

    QueryContainer qDoc=null; 
    foreach (var format in txtDocs) 
    { 
     qDoc|=new TermQuery() {Field="format", Value= format};    
    } 

    var searchResults = client.Search<Document>(s => s.Index(defaultIndex).From(0).Size(50). 
     Query(q => q.Bool(b => b.Should(qDoc).MustNot(qYear)))); 
Смежные вопросы