Postgres表文本字段的弹性搜索

时间:2013-12-05 15:49:39

标签: ruby heroku sinatra elasticsearch

我正在寻找有关如何开始满足以下要求的一些高级建议:

我们有一个在heroku上运行的ruby sinatra API服务,可以将用户的电子邮件与我们的系统同步。

我们将用户的电子邮件存储在postgres数据库中,该数据库分为主题,文本和html字段。

我想使用elasticsearch搜索这些电子邮件,但搜索必须只搜索用户收件箱中的电子邮件。

任何人都可以向我提供如何索引postgres电子邮件表的第一步,以及如何过滤搜索以使其仅限于用户的电子邮件?

电子邮件表的架构是:

CREATE TABLE emails
(
  id serial NOT NULL,
  subject text,
  body text,
  personal boolean,
  sent_at timestamp without time zone,
  created_at timestamp without time zone,
  updated_at timestamp without time zone,
  addresses text,
  account_id integer NOT NULL,
  sender_user_id integer,
  sender_contact_id integer,
  html text,
  folder text,
  draft boolean DEFAULT false,
  check_for_response timestamp without time zone,
  send_time timestamp without time zone,
  send_time_jid text,
  check_for_response_jid text,
  message_id text,
  in_reply_to text,
  CONSTRAINT emails_pkey PRIMARY KEY (id),
  CONSTRAINT emails_account_id_fkey FOREIGN KEY (account_id)
      REFERENCES accounts (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE,
  CONSTRAINT emails_sender_contact_id_fkey FOREIGN KEY (sender_contact_id)
      REFERENCES contacts (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE,
  CONSTRAINT emails_sender_user_id_fkey FOREIGN KEY (sender_user_id)
      REFERENCES users (id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
)

1 个答案:

答案 0 :(得分:2)

听起来您关注搜索目的的唯一字段是body,account_id和文件夹。如果需要,您可以随时添加更多内容(例如,将日期编入索引以启用日期范围搜索可能很有用)。不应分析文件夹名称,以便Elasicsearch不会对其进行干预,您可以使用术语(完全匹配)过滤器来仅检索特定文件夹中的电子邮件。

这是一个仅包含这三个字段的映射:

{
  "email" : {
    "properties" : {
      "account_id" : { "type" : "integer" },
      "body" : { "type" : "string" },
      "folder" : { "type" : "string", "index" : "not_analyzed" },
      "id" : { "type" : "integer" }
    }
  }
}

以下是搜索方式。使用term filters将结果限制为特定文件夹(“收件箱”)和特定用户(account_id = 123)。使用query string查找特定的字词,短语等。

{
  "query": {
    "filtered": {
      "filter": {
        "and": [
          {
            "term": {
              "folder": "Inbox"
            }
          },
          {
            "term": {
              "account_id": 111
            }
          }
        ]
      },
      "query": {
        "query_string": {
          "query": "one"
        }
      }
    }
  }
}