【问题标题】:full text indexing of recursive nested jsonb structures递归嵌套jsonb结构的全文索引
【发布时间】:2015-05-26 09:32:26
【问题描述】:

假设我有一本书是这样表示的:

{ title: "Tis no book"
  chapter: 1,
  text: "Hello world this is a book chapter",
  subchapters: [
     {
     chapter: 1.1
     text: "Nested sub chapter"
     subchapters: [
       chapter: 1.1.1
       text: "Nested nested..."
       subchapters: [ ...etc...]
     },
     {
     chapter: 1.2
     text: "Nested sub chapter 2"
     subchapters: [ ...etc...]
     }
   ]
}

我可以使用 postgres 的 9.4 新 jsonb/gin(或其他任何东西)在此递归嵌套数据结构的 "text" 字段上设置全文索引,以便可以搜索存储到数据库中的图书库通过文本(使用索引)?

【问题讨论】:

    标签: postgresql recursion


    【解决方案1】:

    一个选项(可能是最好的选项)是创建一个递归函数 (official documentation on functions),它将整个 JSONB 结构的 text 值组合成一个字符串(它返回)。您可以对该函数的输出进行全文索引(请参阅@thomas-wayne-shelton 的答案),就好像它只是一个字符串一样。只要您在 WHERE 条件中使用相同的函数,pgSQL 就应该识别索引。

    我刚刚构建/测试了一个类似的“扁平化”功能,所以我相信它可以完成。不幸的是,我的情况非常不同,所以我怀疑代码会混淆而不是启发。我可以说必须将函数标记为 IMMUTABLE 以支持索引。

    ===

    另一条看起来很有希望(但我认为是死胡同)的路径是递归 CTE。

    当然可以使用递归 CTE 解包递归数据。这是official documentation、SO answer 和blog example——最后两个专门用于递归嵌套 JSONB。

    但是,我不相信您可以索引此输出。我的(暂定)理解是,使用递归 CTE 的查询很像视图。这是一个运行时优化。我手头不再有参考资料,但回想起最近(截至 2018 年 4 月)的讨论,即索引视图还有很长的路要走(我什至不确定视图上的索引是否真的适用于 CTE)。

    【讨论】:

      【解决方案2】:

      我刚刚开始研究全文搜索和 jsonb 类型。一旦您了解索引如何在 JSONB 类型上工作,这似乎是可能的。我发现这个博客系列非常有帮助。

      https://bibhas.in/blog/postgresql-swag-part-2-indexing-json-data-type-and-full-text-search/

      此外,Postgres 上有关 JSON 类型的文档包含一些很好的见解。 http://www.postgresql.org/docs/9.4/static/datatype-json.html

      【讨论】:

      • 除非我弄错了,否则这仅显示如何对特定键值(即树中的特定深度)进行全文搜索。我认为 OP 需要回答的问题(以及为什么我发现这个问题)是递归嵌套部分。
      【解决方案3】:

      我不会回答这个问题;相反,我将建议一种完全不同的方法。

      你看过 Lucene,https://lucene.apache.org/core/ 吗?在数据库中实现全文搜索是糟糕的设计。您应该使用单独的全文索引器,例如 Lucene。 Lucene 文档应引用数据库键,用于在数据库中查找真实记录。

      通过使用 Lucene,您很可能会获得比使用数据库的全文搜索功能更好的性能。此外,Lucene 比您的数据库更容易横向扩展。

      【讨论】:

      • 是的,这肯定是首先想到的解决方案,但我正在阅读一些文章,建议在 postgres 中进行全文索引现在很快 (wiki.postgresql.org/images/2/25/…) 并想知道这是否完全可能的。但感谢现实检查。
      • 好吧,如果你决定使用 PostgreSQL 的全文索引,祝你在选择的路径上好运!一种解决方案是将“文本”字段连接到单独的列中,并在该列上使用全文索引。这会导致一些数据重复,但是,嘿,现在磁盘空间很便宜。
      猜你喜欢
      • 2017-08-25
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 2019-02-03
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      相关资源
      最近更新 更多