django 做的网站,wordpress网站用户共享,建设网站需要什么软件,厦门建设局网站文章目录 扁平化处理扁平化处理导致的检索问题 解决方案#xff1a;使用 nested 结构 在es的数据类型中有一个nested类型#xff0c;本讲将重点讨论这个类型。
扁平化处理
PUT my_index/doc/1
{group : fans,user : [{first使用 nested 结构 在es的数据类型中有一个nested类型本讲将重点讨论这个类型。
扁平化处理
PUT my_index/doc/1
{group : fans,user : [{first : John,last : Smith},{first : Alice,last : White}]
}如图所示有一个名为 my_index 的索引其中包含一个文档该文档有一个名为 group 的字符串字段和一个名为 user 的数组字段该数组包含两个对象。
首先看看如何在 Elasticsearch 中处理此数据然后讨论如何解决扁平化处理带来的挑战。
默认情况下Elasticsearch 将尝试将数组内的对象展平。在这种情况下Elasticsearch 可能会将 user 数组展平为以下形式
{group: fans,user.first: [John, Alice],user.last: [Smith, White]
}然而这种扁平化处理并不能很好地反映原始数据结构因为它丢失了用户对象的上下文。
扁平化处理导致的检索问题
因此我们在查询时会遇到下面的问题。
GET my_index/_search
{query: {bool: {must: [{match: {user.first: Alice}},{match: {user.last: Smith}}]}}
}在扁平化处理下user 数组中的对象会被展平为单独的字段例如 user.first 和 user.last。这意味着每个用户对象的属性都会被拆分为独立的字段而不是作为一个整体存储。
在给定的查询中要匹配一个 user 对象其中 first 属性等于 “Alice”last 属性等于 “Smith”。由于扁平化处理user.first 和 user.last 字段分别包含 “John”、“Alice” 和 “Smith”、“White”而不是完整的 “Alice Smith”。
在扁平化处理的情况下这个查询可能会返回错误的结果即使文档中不存在一个完整的 “Alice Smith” 用户。这是因为查询引擎会将 “Alice” 和 “Smith” 视为独立的关键词而不是一个完整的姓名。因此只要文档中存在一个 user.first 匹配 “Alice” 和一个 user.last 匹配 “Smith”无论它们是否来自同一个用户对象都会被视为匹配项。
对于上图中的查询语义是要查找一个叫做“Alice Smith”的人实际上并没有这样一个人但是因为ES的扁平化处理检索过程如下
首先会在user.first中查找Alice能够匹配到一条记录接着在user.last中查找Smith也能够匹配到
最后能查到两条记录与预期不符。
解决方案使用 nested 结构
为了避免这些问题我们可以使用 nested 类型来存储 user 数组。以下是使用 nested 类型的映射定义
PUT my_index
{mappings: {properties: {group: { type: keyword },user: {type: nested,properties: {first: { type: keyword },last: { type: keyword }}}}}
}现在我们可以将相同的数据插入到索引中但这次使用 nested 结构
PUT my_index/doc/1
{group: fans,user: [{ first: John, last: Smith },{ first: Alice, last: White }]
}使用 nested 结构的好处在于它可以保留数组中每个对象的完整结构。这意味着我们可以对 user 数组中的单个元素执行更复杂的查询而不仅仅是简单的过滤。
例如我们可以查询姓氏为 White 的用户
GET my_index/_search
{query: {nested: {path: user,query: {term: {user.last.keyword: White}}}}
}上述查询将返回所有包含至少一个姓氏为 White 的用户。
使用 nested 结构可以帮助我们更好地处理对象数组特别是当我们需要执行更复杂的查询时。虽然 nested 结构可能会带来更高的存储成本和查询性能影响但它提供了更大的灵活性和准确性。