Search code examples
c#elasticsearchnestedelasticsearch-queryelasticsearch-2.0

Elastic Search 2.0 search query in main object and nested object


This is my model:

public class Student
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }

    [Nested]
    public List<Subject> Subjects { get; set; }
}

public class Subject
{
    public int Id { get; set; }
    public string SubjectName { get; set; }        
}

Mapping:

mappings: {
  student: {
    properties: {
      firstName: {
        type: "string"
      },
      id: {
        type: "integer"
      },
      lastName: {
        type: "string"
      },
      subjects: {
        type: "nested",
        properties: {
          id: {
            type: "integer"
          },
          subjectName: {
            type: "string"
          }
       } 
    }
 }
}
}

To search inside the nested object (Subject) I use following code and it returns the values correctly.

var searchResponse = client.Search<Student>(s => s    
.Query(q => q
    .Nested(n => n
        .Path(p => p.VolunteerTasks)
        .Query(nq => nq.Match(m => m
            .Query(searchText).Field("subjects.subjectName"))))));
 return searchResponse.Documents;

But I want to search with the same searchText for student.firstName, student.lastName and subjects.subjectName. How can I do that?


Solution

  • You need to add a should clause with a match query on first name and last name and a nested query on subject name. You cannot club nested and non nested query in a single match or multi-match query

    var searchResponse = _elasticClient.Search<AssociateProfile>(s => s
                         .Query(q => q
                                     .Bool(b=>b
                                                 .Should(
                                                            sh => sh.Match(m => m.Query(searchText).Field("student.firstName")),
                                                            sh => sh.Match(m => m.Query(searchText).Field("student.lastName")),
                                                             sh => sh.Nested(n => n
                                                                                   .Path(p => p.VolunteerTasks)                                                                                           .Query(nq => nq.Match(m => m                                                                                           .Query(searchText).Field("subjects.subjectName")))
                                                                                        )
    
                                                                       )
                                                        )
                                                  ));