如何使用 C# NEST 在 ElasticSearch 中搜索数组的动态元素?

如何解决如何使用 C# NEST 在 ElasticSearch 中搜索数组的动态元素?

我的 elasticsearch 中有这些数据,具有这种结构。

enter image description here

如何从这个数组中搜索名字、中间名和姓氏?注意:NameDetails 数组长度是动态的。人 A 可能只有 NameDetails一个元素。人 B 可以有 3 个 NameDetails 元素。

目前,我只能按 gender 搜索。我正在使用 nesT nuget C#。这是我的查询

var response = await _elasticclient.SearchAsync<Person>(s => s
          .Query(q => q
              .Bool(b => b.Must(
                mu => mu
                .Match(m => m
                 .Field(f => f.Gender)
                 .Query(Gender)
                )

                )
              )
          )
        );

enter image description here

nesT 中,我尝试使用此代码但未返回任何结果。

        var response = _elasticclient.Search <Model.Entities.Split.Person.Person> (s => s
            .Index("person")
            .Query(q => q
                .Match(m => m
                    .Field(f => f.NameDetails.Name[0].NameValue.FirstName)
                    .Query("Fawsu")
                )
            )
        );

但是如果我直接在 ElasticSearch 上使用下面的查询运行 DSL 查询,它会返回结果。

GET /person/_search
{
  "query": {
    "match": {
          "nameDetails.nameValue.firstName": {
            "query": "Fawsu"
          }
        }
    }
  }
}

GET /person/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "fuzzy": {
            "nameDetails.nameValue.surname": {
              "value": "Pibba","fuzziness": "AUTO"
            }
          }
        },{
          "fuzzy": {
            "nameDetails.nameValue.firstName": {
              "value": "Fawsu","fuzziness": "AUTO"
            }
          }
        }
      ]
    }
  }
}

解决方法

了解如何将其映射到 POCO 很有用

public class Person
{
    public string Gender { get; set; }
    public string ActiveStatus { get; set; }
    public string Deceased { get; set; }
    public List<Name> NameDetails { get; set; }
}

public class Name
{
    public List<NameValue> NameValue { get; set; }
    public string NameType { get; set; }
}

public class NameValue
{
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
}

(您可能会将其中一些字段映射为字符串以外的类型,我将把它留给读者作为练习)。

搜索名字

var client = new ElasticClient();


var response = client.Search<Person>(s => s
    .Index("people")
    .Query(q => q
        .Match(m => m
            .Field(f => f.NameDetails[0].NameValue[0].FirstName)
            .Query("Fawsu")
        )
    )
);

产生查询

POST http://localhost:9200/people/_search?pretty=true&typed_keys=true 
{
  "query": {
    "match": {
      "nameDetails.nameValue.firstName": {
        "query": "Fawsu"
      }
    }
  }
}

.Field(f => f...) 中的表达式是构建 "nameDetails.nameValue.firstName" 路径的表达式,它将在 any 名称值和名称详细信息的名字中查找匹配项。它使用索引器的事实意味着它针对名字详细信息的名字值,而只是一种遍历对象图以构建表达式的方法。

要构建复合查询以针对 same 名称值的多个值,NameNameValue 都需要为 mapped as nested data types,然后嵌套将使用查询。

对于单个字段

var response = client.Search<Person>(s => s
    .Index("people")
    .Query(q => q
        .Nested(n => n
            .Path(f => f.NameDetails)
            .Query(nq => nq
                .Nested(nn => nn
                    .Path(f => f.NameDetails[0].NameValue)
                    .Query(nnq => nnq
                        .Match(m => m
                            .Field(f => f.NameDetails[0].NameValue[0].FirstName)
                            .Query("Fawsu")
                        )
                    )
                )
            )
        )
    )
);

对于多个字段

var response = client.Search<Person>(s => s
    .Index("people")
    .Query(q => q
        .Nested(n => n
            .Path(f => f.NameDetails)
            .Query(nq => nq
                .Nested(nn => nn
                    .Path(f => f.NameDetails[0].NameValue)
                    .Query(nnq => nnq
                        .Bool(b => b
                            .Must(m => m
                                .Match(m => m
                                    .Field(f => f.NameDetails[0].NameValue[0].FirstName)
                                    .Query("Fawsu")
                                ),m => m
                                .Match(m => m
                                    .Field(f => f.NameDetails[0].NameValue[0].LastName)
                                    .Query("Pibba")
                                )
                            )
                        )
                    )
                )
            )
        )
    )
);

后者导致查询

POST http://localhost:9200/people/_search?pretty=true&typed_keys=true 
{
  "query": {
    "nested": {
      "path": "nameDetails","query": {
        "nested": {
          "path": "nameDetails.nameValue","query": {
            "bool": {
              "must": [
                {
                  "match": {
                    "nameDetails.nameValue.firstName": {
                      "query": "Fawsu"
                    }
                  }
                },{
                  "match": {
                    "nameDetails.nameValue.lastName": {
                      "query": "Pibba"
                    }
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}
,

如果您想搜索以下内容:

firstName == "John" AND middleName == "Ben" AND lastName == "smith"

然后您可以使用TermQuery来搜索firstNamemiddleNamelastName

我更熟悉Object Initializer Syntax(需要using static Nest.Infer

using static Nest.Infer;

var query = new TermQuery
{
    Name = "my firstName query",Field = Field<Person>(p => p.firstName),Value = "John"
};

您需要为 middleNamelastName 再编写 2 个查询,然后为所有这些查询编写 AND


如果您想搜索以下内容:

firstName == "John" OR middleName == "John" OR lastName == "John"

然后你可以使用Multi-match Query

using static Nest.Infer;

var query = new MultiMatchQuery
{
    Name = "My Multi-match query",Fields = Field<Person>(p => p.firstName,1.1) // 1.1 is boost (default is 1)
        .And<AdDocument>(p => p.middleName,1)
        .And<AdDocument>(p => p.lastName,1)
    Query = "John"
    //Fuzziness = Fuzziness.Auto
};

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?