json - Elasticsearch 查询的无模式支持

标签 json elasticsearch schemaless

我们的 REST API 允许用户将自定义无模式 JSON 添加到我们的一些 REST 资源中,我们需要它可以在 Elasticsearch 中进行搜索。此自定义数据及其结构在同一类型的资源中可能完全不同。

考虑这个示例文档:

{
  "givenName": "Joe",
  "username": "joe",
  "email": "joe@mailinator.com",
  "customData": {
    "favoriteColor": "red",
    "someObject": {
      "someKey": "someValue"
    }
  } 
}

customData 之外的所有字段都遵循模式。 customData 始终是一个 JSON 对象,但该对象中的所有字段和值可能因资源而异。无法保证 customData 中的任何给定字段名称或值(甚至值类型)在任何两个资源中都是相同的,因为用户可以根据需要编辑这些字段。

支持对此进行搜索的最佳方式是什么?

我们认为一个解决方案是在创建索引时不为 customData 创建任何映射,但随后它变得不可查询(这与 ES docs say 相反)。如果对非映射属性的查询有效,这将是理想的解决方案,并且这种方法没有性能问题。然而,在针对该问题进行了多次测试之后,我们无法让它发挥作用。

这是否需要任何特殊配置?或者文档不正确?将不胜感激关于为什么它不起作用的一些澄清。

由于目前这对我们不起作用,我们想到了几个替代解决方案:

  1. 重建索引:这会很昂贵,因为我们需要重建包含该文档的每个索引,并且每次用户使用不同的值类型更新属性时都需要这样做。对性能来说真的很糟糕,所以这可能不是一个真正的选择。

  2. 使用 multi-match query :每次 customData 对象发生变化时,我们都会通过将随机字符串附加到 customData 字段名称来实现。例如,这是被索引的文档的样子:

    {
      "givenName": "Joe",
      "username": "joe",
      "email": "joe@mailinator.com",
      "customData_03ae8b95-2496-4c8d-9330-6d2058b1bbb9": {
        "favoriteColor": "red",
        "someObject": {
          "someKey": "someValue"
        }
      }
    }
    

    这意味着 ES 会为每个“随机”字段创建一个新的映射,并且我们会在执行查询时使用“开头为”通配符作为字段名称的短语多匹配查询。例如:

    curl -XPOST 'eshost:9200/test/_search?pretty' -d '
    {
      "query": {
        "multi_match": {
          "query" : "red",
          "type" :  "phrase",
          "fields" : ["customData_*.favoriteColor"]
        }
      }
    }'
    

    这可能是一个可行的解决方案,但我们担心这样的映射过多会影响性能。索引上的映射过多是否会对性能产生影响?也许定期重建索引可以缓解映射过多的问题?

    这也感觉像是一个 hack,应该由 ES native 处理。我错过了什么吗?

如有任何建议,我们将不胜感激。

谢谢!

最佳答案

您说得对,Elasticsearch 并非真正无模式。如果未指定映射,Elasticsearch 会根据它看到的该字段的第一个值来推断字段类型原语。因此,如果您首先看到 "favoriteColor": 10,然后是 "favoriteColor": "red",您的非确定性 customData 对象可能会给您带来麻烦。

根据您的要求,您应该查看SIREn Solutions Elasticsearch plugin它提供了一种无模式解决方案,结合了一种高级查询语言(使用 Twig)和一种自定义 Lucene 索引格式,以加速非确定性数据的索引和搜索操作。

关于json - Elasticsearch 查询的无模式支持,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31171987/

相关文章:

javascript - 无法将两个对象与 Json.parse 和 Json.stringify 联合起来

javascript - 单击列表项后显示子列表

amazon-web-services - elasticsearch:EC2发现:主节点工作数据节点失败

amazon-web-services - AWS Elasticsearch EC2 Discovery,无法找到其他节点

database - 具有动态模式的数据库的 DBMS 选择方法?

json - 替换空字符串

java - 如何将 Restful 服务上的字符串转换为 xml 文件以进行 xsd 验证

elasticsearch - 带有过滤器的 More_like_this 查询

json - HBase从具有行ID的任意JSON插入

nosql - 将关系数据库用于无模式数据-最佳实践