1

I need to get the documents from ES using NEST client with multiple And/OR conditions on two fields.

My query is as:

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

below is my code:

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()))));

When I try this code it works for the years that must not appear in the results but for the formats that should be selected by user, it doesn't show those selected formats although they are available. I also used "must" instead of "should", but then it does not retrieve anything at all.

Has anyone had such a similar problem?

Mahsa
  • 341
  • 3
  • 17

2 Answers2

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"))
        )
    )));

Hope it helps.

Rob
  • 9,664
  • 3
  • 41
  • 43
  • Thanks Rob! Actually, I was looking for a code that make a dynamic query since user can select several formats and years. So, finally based on your answer I got where I was wrong! format field should be "Not analyzed" and then my code which is added as a new answer works well! – Mahsa Nov 27 '15 at 11:22
1

Here is the code for making a dynamic query:

 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))));
Mahsa
  • 341
  • 3
  • 17