递归嵌套jsonb结构的全文索引

时间:2015-03-23 11:49:40

标签: postgresql recursion

让我们说我有一本这样的书:

{ 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"字段上设置全文索引,以便可以通过文本搜索存储到数据库的书库(使用索引) )?

3 个答案:

答案 0 :(得分:4)

我刚开始研究全文搜索和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

答案 1 :(得分:2)

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

我刚刚建立/测试了类似的"展平"功能,所以我相信它可以做到。不幸的是,我的情况非常不同所以我怀疑代码会混淆而不是启发。我可以说必须将函数标记为IMMUTABLE以支持索引。

===

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

使用递归CTE打包递归数据当然是可能的。这里是official documentationSO answerblog example - 特别是递归嵌套JSONB的最后两个。

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

答案 2 :(得分:-1)

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

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

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