我有两个来自同一索引的文档,它们最初看起来像这样(只有 _source
(此处显示值)
{
"id" : "3",
"name": "Foo",
"property":{
"schemaId":"guid_of_the_RGB_schema_defined_extenally",
"value":{
"R":255,
"G":100,
"B":20
}
}
}
{
"id" : "2",
"name": "Bar",
"property":{
"schemaId":"guid_of_the_HSL_schema_defined_extenally",
"value":{
"H":255,
"S":100,
"L":20
}
}
}
架构(用于验证 value
)存储在es之外,因为它与索引无关。如果我不定义Map value
现场将被考虑 Object
Map。一旦有了新的子域,它的子域就会增长。
目前,elasticsearch支持展平Maphttps://www.elastic.co/guide/en/elasticsearch/reference/current/flattened.html 以防止索引中出现这种爆炸。但是,由于其限制,它对搜索内部场的支持有限: As with queries, there is no special support for numerics — all values in the JSON object are treated as keywords. When sorting, this implies that values are compared lexicographically.
我需要能够查询索引以找到与给定文档匹配的文档(例如,范围[10,30]中的b)
到目前为止,我想出了一个解决方案,把我的医生组织成这样
{
"id":4,
"name":"Boo",
"property":
{
"guid_of_the_normalized_RGB_schema_defined_extenally":
{
"R":0.1,
"G":0.2,
"B":0.5
}
}
虽然它并没有解决我的Map爆炸问题,但它减轻了其他一些问题。我现在的Map将类似于这个字段 property
```
"property": {
"properties": {
"guid_of_the_RGB_schema_defined_extenally": {
"properties": {
"B": {
"type": "long"
},
"G": {
"type": "long"
},
"R": {
"type": "long"
}
}
},
"guid_of_the_normalized_RGB_schema_defined_extenally": {
"properties": {
"B": {
"type": "float"
},
"G": {
"type": "float"
},
"R": {
"type": "float"
}
},
"guid_of_the_HSL_schema_defined_extenally": {
"properties": {
"B": {
"type": "float"
},
"G": {
"type": "float"
},
"R": {
"type": "float"
}
}
}
}
}
这解决了字段名称相同但数据类型不同的问题。
有人能给我建议一个解决方案,解决指数爆炸的问题,而不受 `Flattened` 你在找什么?
1条答案
按热度按时间mrzz3bfm1#
为了避免Map爆炸,最好的解决方案是更好地规范化数据。您可以在Map中设置“dynamic”:“strict”,如果一张单据包含Map中尚未包含的字段,则该单据将被拒绝。之后,仍然可以添加新字段,但必须在Map之前显式添加它们。
您可以添加一个管道,以便在接收数据之前对数据进行清理和规范化。
如果不需要或无法重新索引:
为了使您的查询更容易,即使您不知道您的关键的“中间”部分,您可以使用一个星的多重匹配。
但你仍然无法按你的意愿对它进行排序。要在不接触数据的情况下对多个“未知”字段名进行排序,可以使用脚本:https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-sort-context.html
但也许你可以通过在索引中添加一个动态模板来简化整个过程。
然后您可以使用相同的查询查询任何值:
对于已经存在的字段,您必须自己在Map中添加副本,然后运行一个\u update \u by \u查询来填充它们。