【问题标题】:Elasticsearch - search for keys inside nested field value, which is a jsonElasticsearch - 在嵌套字段值中搜索键,这是一个 json
【发布时间】:2020-12-30 03:02:39
【问题描述】:

我在尝试执行的查询方面需要一些帮助。

我的一个索引中有一个名为 scores 的字段,该字段将一些 AI 模型分数存储为 json。该字段的基本结构如下(显示索引中的几条记录):

[{"scores":
    {"a/b": 1.231,
     "a/c": 23.11,
     "x/a": 1232.1}},
 {"scores":
    {"a/d": 3.1}}]

映射类似于:

{"scores":
  {"properties":
    {"a/b": {"type":"float"},
     "a/c": {"type":"float"},
     "a/d": {"type":"float"}}}}

字段分数的值,即另一个 json 将具有任意字段,即我不会事先知道 json 中存在哪些字段。

我想要做的是搜索 json 中的键,即如果我搜索 a/,它应该返回 ["a/b", "a/d", "a/c"] .

我知道这可以通过嵌套查询实现,但看起来我需要重新映射我的索引,以便字段分数具有更扁平的数据结构。但是我现在不想这样做,只想使用现有结构并执行我的查询。

如果有人对此有任何想法,请按我的方式提出。

【问题讨论】:

  • 那么当前的映射是什么?
  • @JoeSorocin 我用映射更新了问题。
  • 好的,但仍不清楚您想要实现什么...您是否正在构建查询并且只想定位a/-prefixed 字段?
  • @JoeSorocin 没错,我想获取以a/ 开头的字段。
  • “获取字段”是什么意思?

标签: elasticsearch


【解决方案1】:

您可以使用_source 来限制检索的内容:

POST indexname/_search
{
 "_source": "scores.a/*"
}

或者,您可以使用 script_fields,它的作用完全相同,但也提供了修改价值的空间:

POST indexname/_search
{
  "script_fields": {
   "scores_prefixed_with_a": {
     "script": {
       "source": """params._source.scores.entrySet()
                        .stream()
                        .filter(e->e.getKey().startsWith(params.prefix))
                        .collect(Collectors.toMap(e->e.getKey(),e->e.getValue()))""",
       "params": {
         "prefix": "a/"
       }
     }
   }
 }
}

【讨论】:

  • 是的。我不得不稍微修改查询,我应该在这里发布对您答案的编辑。但由于某种原因,它说建议队列已满。
【解决方案2】:

在Object.keys() 上使用.filter() - .reduce()

const data = [{"scores": {"a/b": 1.231, "a/c": 23.11, "x/a": 1232.1}}, {"scores": {"a/d": 3.1}}];

const allowed = 'a/';

const res = data.map((d) => 
    Object.keys(d.scores)
    .filter(key => key.startsWith(allowed)))
    .reduce((prev, curr) => prev.concat(curr)); 

console.log(res)
[
  "a/b",
  "a/c",
  "a/d"
]


原创,用对象代替关闭键;

const data = [{"scores": {"a/b": 1.231, "a/c": 23.11, "x/a": 1232.1}}, {"scores": {"a/d": 3.1}}];

const allowed = 'a/';

const res = data.map((d) => 
  Object.keys(d.scores)
    .filter(key => key.startsWith(allowed))
    .reduce((obj, key) => { obj[key] = d.scores[key]; return obj; }, {})); 
console.log(res);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多