主对象和嵌套对象中的 Elastic Search 2.0 搜索查询

Elastic Search 2.0 search query in main object and nested object

这是我的模型:

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

映射:

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

为了在嵌套对象 (Subject) 中搜索,我使用了以下代码,它 returns 正确地获取了值。

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;

但我想使用相同的搜索文本搜索 student.firstNamestudent.lastNamesubjects.subjectName。 我该怎么做?

以 REST 形式提供答案 API,您可以将其转换为 c# 格式,因为我不熟悉它的语法,这对不寻找特定语言答案的人会有帮助.

使用您的示例数据对此进行了测试,下面是有效的解决方案

索引定义

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

** 没有 opster subjectfirstname 的索引示例文档 **

{
    "firstName": "Isuru",
    "lastName": "foo",
    "id": 1,
    "subjects": [
        {
            "id": 100,
            "subjectName": "math"
        },
        {
            "id": 101,
            "subjectName": "opster"
        }
    ]
}

索引另一个主题名称中没有 opster 的文档

{
    "firstName": "opster",
    "lastName": "tel aviv",
    "id": 1,
    "subjects": [
        {
            "id": 100,
            "subjectName": "math"
        },
        {
            "id": 101,
            "subjectName": "science"
        }
    ]
}

搜索查询,请根据您的要求将must改为should

{
    "query": {
        "bool": {
            "should": [    --> note
                {
                    "match": {
                        "firstName": "opster"
                    }
                },
                {
                    "nested": {
                        "path": "subjects",
                        "query": {
                            "bool": {
                                "must": [   -->note
                                    {
                                        "match": {
                                            "subjects.subjectName": "opster"
                                        }
                                    }
                                ]
                            }
                        }
                    }
                }
            ]
        }
    }
}

搜索结果

"hits": [
            {
                "_index": "nested",
                "_type": "student",
                "_id": "1",
                "_score": 0.39103588,
                "_source": {
                    "firstName": "opster",
                    "lastName": "tel aviv",
                    "id": 1,
                    "subjects": [
                        {
                            "id": 100,
                            "subjectName": "math"
                        },
                        {
                            "id": 101,
                            "subjectName": "science"
                        }
                    ]
                }
            },
            {
                "_index": "nested",
                "_type": "student",
                "_id": "2",
                "_score": 0.39103588,
                "_source": {
                    "firstName": "Isuru",
                    "lastName": "foo",
                    "id": 1,
                    "subjects": [
                        {
                            "id": 100,
                            "subjectName": "math"
                        },
                        {
                            "id": 101,
                            "subjectName": "opster"
                        }
                    ]
                }
            }
        ]

您需要添加一个包含名字和姓氏匹配查询的 should 子句 和主题名称的嵌套查询。您不能将嵌套和非嵌套查询组合在单个匹配或多匹配查询中

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

                                                                   )
                                                    )
                                              ));

根据 OP 的评论,添加提供部分匹配的答案。就像如果文档包含 Science and technology 并且搜索 techno 也应该来。 请注意使用自定义 edge-n-gram 分析器来实现此要求。

索引定义

{
  "settings": {
    "analysis": {
      "filter": {
        "autocomplete_filter": {
          "type": "edge_ngram",
          "min_gram": 1,
          "max_gram": 10
        }
      },
      "analyzer": {
        "autocomplete": { 
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "autocomplete_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "autocomplete", 
        "search_analyzer": "standard" 
      }
    }
  }
}

索引示例文档

{
    "title" : "Science and technology"
}

搜索查询

{
    "query" :{
        "match" :{
            "title" :"techno"
        }
    }
}

搜索结果

 "hits": [
            {
                "_index": "edge",
                "_type": "_doc",
                "_id": "1",
                "_score": 0.44104567,
                "_source": {
                    "title": "Science and technology"
                }
            }
        ]