【问题标题】:Ruby and PostgreSQL text matchingRuby 和 PostgreSQL 文本匹配
【发布时间】:2014-08-29 11:37:48
【问题描述】:

我正在尝试使用 PostgreSQL 在 Ruby 中进行一些文本匹配。

这是我的代码:

require 'active_record'
require 'yaml'
require 'pg'
require 'pry'

$config = '
adapter: postgresql
database: edgar
username: YYYYY
password:
host: 127.0.0.1'

ActiveRecord::Base.establish_connection(YAML::load($config))
class Doc < ActiveRecord::Base; end
class Filing < ActiveRecord::Base; end

#Searching database edgar and table for key words

#install gem install pg_search

class Filing < ActiveRecord:: Base
    include PgSearch
end


class Filing < ActiveRecord::Base
    pg_search_score:search_eightks,
    :against => [:cancer, heart attack] 
end

我有几个问题:

  1. 如何搜索我的数据库的 eightks 表?
  2. 如何搜索多个单词?我想查看文档中是否包含“癌症”或“心脏病发作”一词。它不需要两者,只需要一个或另一个。

这是数据库中关系列表的样子:

埃德加=# \d 关系列表 架构 |姓名 |类型 |所有者 --------+-----------+----------+------ ------------ 公共 | crsp_ccm_lookup |表|年年 公共 |文档 |表|年年 公共 | docs_downloaded |表|年年 公共 | docs_id_seq |序列 |年年 公共 |文档类型 |表|年年 公共 | document_types_id_seq |序列 |年年 公共 |八点 |表|年年 公共 |备案|表|年年 公共 |归档_for_run |表|年年 公共 |归档_id_seq1 |序列 |年年 公共 |指数 |表|年年 公共 |索引_id_seq |序列 |年年 公共 | scraper_groups |表|年年 公共 | scraper_groups_id_seq |序列 |年年 公共 | ws |查看 |年年 公共 | ws_table |表|年年 公共 | z_docs_10_ks |表|年年 (17 行)

理想情况下,当找到包含这些单词的文本文档时,我想将其复制到新文件夹中。

非常感谢任何帮助。

【问题讨论】:

  • 不要创建像$config 这样的全局变量,除非您明白为什么需要全局变量,这非常罕见。使用它们暗示了变量作用域的味道以及缺乏对变量在 Ruby 中如何工作的理解。

标签: ruby postgresql


【解决方案1】:

关于上面代码的一些事情:

  1. 不太清楚你为什么要连续两次开课(而且是第三次)
  2. 我相信pg_search_scope(注意p而不是r)是正确使用的术语(我在pg_search的代码中没有看到pg_search_score

所以是这样的:

class Filing < ActiveRecord::Base
    include PgSearch

    pg_search_scope:search_eightks,
    :against => [:cancer, heart attack] 
end

但是,我想知道您是否真的想在这里使用全文搜索,因为这是 Postgres 的一个合理的小众用例。

例如,如果文档只是text 类型,您可以对它们运行正则表达式来检查(或字符串函数之一)。现在,如果它们是大型文档,或者如果您想做一些更高级的事情,比如对搜索结果进行排名(有点像 Solr 的方式),那么全文可能值得一看。

您要在这里完成的总体情况是什么? (不是如何,而是什么/为什么?)还需要有关所涉及表的定义以及 Postgres 的版本的更多信息。

另外,不太清楚您所说的将其复制到新文件夹是什么意思。 文件夹Postgres 中没有任何意义。您是否将 Postgres 术语与应用程序逻辑中的术语混合在一起?

根据 OP 的评论进行编辑:

根据您的 cmets 大约有 200,000 个文档(这听起来像是一个相当小的数据集,除非文档本身绝对巨大),并且您想检查其中是否包含一些关键字,假设文档是文本(听起来像是)我建议使用 Postgres 正则表达式。

作为示例,假设文档文本存储在 docs 表中名为 contents 的列中,您可以执行以下操作:

SELECT *
FROM docs
WHERE contents ~* 'heart attack|cancer|illness';

ActiveRecord 允许您通过 connection.execute 方法使用原始 SQL,您可以将上述查询作为字符串传递。

然后您可以根据需要进一步处理它们。

我并不是说您永远不需要对这类事情使用全文搜索,只是我不建议您从那里开始,尤其是根据您提供的有关您的用例的信息和数据。

根据 OP 的后续评论进行编辑:

你说你使用的代码:

require
    Select * from eightks where contents ~* 'heart attack | cancer |illness'
end

无效Ruby。您需要begin 来搭配end,而不是require,并且SQL 需要是传递给Active Record 对象的connection.execute 方法的字符串。上面的代码中似乎没有列出连接对象。可能它是您定义的 Filing 类的一个实例。

此外,contents 列仅在您的表定义中确实包含该列时才有效。这只是示例——您需要对其进行调整以适合您的特定表格。

如果您在让原始 SQL 在您的场景中工作时遇到其他问题,则应该将其拆分为一个单独的问题,因为这个问题变得相当长并且转向单独的(尽管相关)问题。您可以链接此问题以获取更多上下文。

【讨论】:

  • 嗨@Ken_Hampson .. 非常感谢您的详细回复。我有大约 200,000 个文本文档。我正在尝试查看这些文档是否包含某些单词的列表。例如,文件是否提到癌症、心脏病发作、疾病。一旦找到包含这些单词中的任何一个的文档,我想知道它是哪个文档,以便进一步检查它。我只使用 Pg_search 是因为我在另一个论坛上遇到过它。很抱歉对这件事这么陌生。
  • 当然,没问题。我将在上面的答案中添加一些内容。
  • 嗨@Ken_Hampson...非常感谢您的帮助。当我这样做时,我在终端 ruby​​ edgar_demo.rb edgar_demo.rb:22 中收到以下错误:语法错误,意外 tIDENTIFIER,期望关键字_do 或 '{' 或 '(' edgar_demo.rb:23: 语法错误,意外 * where内容〜*'心脏病发作|癌症|疾病'^ edgar_demo.rb:23:语法错误,意外'\n',期待::或'['或'.'。不知道为什么?这是我的红宝石代码要求 Select * from Eightks where contents ~* 'heart attack | cancer |illness' end
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 1970-01-01
  • 1970-01-01
  • 2018-04-20
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
相关资源
最近更新 更多