Elasticsearch nested类型的用法(附带实例)
nested 类型是一种专用的 object 类型形式,它维护了文档中对象数组之间的关系。
举一个电子邮件和附件的示例,我们将 attachments 字段定义为 nested 数据类型,而不是让 Elasticsearch 将其推断为 object 类型。这需要通过声明 attachments 字段为 nested 数据类型来创建模式,示例代码如下:
我们已经有了模式定义,需要做的就是索引一个文档,示例代码如下:
一旦该文档成功索引,拼图的最后一块就是搜索。下面的示例代码展示了用于获取文档的搜索查询,搜索条件是带有附件的电子邮件,其中文件名和文件分类分别为 file1.txt 和 private。因为这种组合不存在,所以结果一定为空,这与使用 object 类型的情况不同,使用 object 类型时,数据是跨文档搜索的,会导致假阳性结果。
nested 数据类型擅长维护关联和关系。如果需要创建对象数组,而每个对象都必须被视为一个单独的对象,那么 nested 数据类型可能是好的选择。
举一个电子邮件和附件的示例,我们将 attachments 字段定义为 nested 数据类型,而不是让 Elasticsearch 将其推断为 object 类型。这需要通过声明 attachments 字段为 nested 数据类型来创建模式,示例代码如下:
PUT emails_nested
{
"mappings": {
"properties": {
"attachments": { ←--- 将attachments字段声明为nested类型
"type": "nested",
"properties": {
"filename": { ←--- 将filename字段声明为keyword类型以避免分词
"type": "keyword"
},
"filetype": {
"type": "text" ←--- 将该字段保留为text类型
}
}
}
}
}
}
除了将 attachments 字段创建为 nested 类型,我们还将 filename 声明为 keyword 类型。filename 字段的值会被分词,例如 file1.txt 被拆分成 file1 和 txt。因此,搜索查询可能与 txt 和 confidential 或 txt 和 private 匹配,因为这两条记录都有 txt 作为公共的词元。为了避免这种情况,我们可以将 filename 作为 keyword 类型的字段。我们已经有了模式定义,需要做的就是索引一个文档,示例代码如下:
PUT emails_nested/_doc/1
{
"attachments" : [ ←--- 提供几个对象作为附件
{
"filename" : "file1.txt",
"filetype" : "confidential"
}
{
"filename" : "file2.txt",
"filetype" : "private"
}
]
}
一旦该文档成功索引,拼图的最后一块就是搜索。下面的示例代码展示了用于获取文档的搜索查询,搜索条件是带有附件的电子邮件,其中文件名和文件分类分别为 file1.txt 和 private。因为这种组合不存在,所以结果一定为空,这与使用 object 类型的情况不同,使用 object 类型时,数据是跨文档搜索的,会导致假阳性结果。
GET emails_nested/_search
{
"query": {
"nested": { ←--- 使用nested查询搜索nested字段中的数据
"path": "attachments", ←--- 指向nested字段的路径
"query": {
"bool": {
"must": [ ←--- 搜索子句:必须匹配file1.txt和private
{ "match": { "attachments.filename": "file1.txt" }},
{ "match": { "attachments.filetype": "private" }}
]
}
}
}
}
}
该查询搜索名为 file1.txt 且分类为 private 的文件,这样的文件并不存在。这个查询没有返回任何文档,这正是我们所期望的。file1.txt 的分类是 confidential,不是 private,因此它不匹配。当 nested 类型表示一个内部对象的数组时,每个单独的对象都被存储和索引为一个隐藏的文档。nested 数据类型擅长维护关联和关系。如果需要创建对象数组,而每个对象都必须被视为一个单独的对象,那么 nested 数据类型可能是好的选择。
ICP备案:
公安联网备案: