rails elasticsearch搜索嵌套的json字段

时间:2014-10-30 13:59:02

标签: ruby-on-rails elasticsearch elasticsearch-model

我将elasticsearch-model gem用于具有has_many关系的模型。为了匹配文档,我们假设模型为Article,关系为has_many categories。所以我按如下方式(直接从文档中)编写了客户序列化程序:

def as_indexed_json(options={})
  self.as_json(
    include: { categories: { only: :title},
             })
end

序列化似乎有效。示例文章的as_indexed_json的结果包含"categories" => {"title"=> "one", "title"=> "two", "title"=> "three"}块。

我在文档中遇到的并且无法找到的是如何搜索此嵌套字段。

以下是我尝试的内容:

从我elasticsearch documentation on nested query我认为它应该是这样的:

r = Article.search query: {
    nested: {
        path: "categories",
        query: {match: {title: "one"}}
    }
}

但是当我r.results.first时,我收到错误:nested object under path [categories] is not of nested type] ...

我尝试添加将序列化程序中的一行更改为:include: { categories: { type: "nested", only: :title},但这并没有改变任何内容,它仍然表示类别不是嵌套类型。

当然,我只是尝试查询字段而没有任何嵌套:

r = Article.search query: {match: {categories: 'one'}}

但这并没有带来任何结果。

像这样的全文搜索:

r = Article.search query: {match: {_all: 'one'}}

返回结果,但当然我只想搜索一个'在类别字段中。

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

好的,看起来好像:r = Article.search query: {match: {"categories.title" => 'one'}}有效,但我会保留问题,万一有人可以解释嵌套事物发生了什么......

答案 1 :(得分:0)

Rails不会在elasticsearch中创建嵌套映射。 Elasticsearch使用动态映射将类别作为对象而不是嵌套子类("当Elasticsearch遇到文档中以前未知的字段时,它使用动态映射来确定字段的数据类型并自动将新字段添加到类型中映射为对象而不嵌套它们#34;)。要使它们成为嵌套对象,您需要在elasticsearch中再次创建映射,类别为嵌套类型,通知类型为嵌套类别。

 PUT /my_index 
{
  "mappings": {
    "article": {
      "properties": {
        "categories": {
          "type": "nested", 
          "properties": {
            "name":    { "type": "string"  },
            "comment": { "type": "string"  },
            "age":     { "type": "short"   },
            "stars":   { "type": "short"   },
            "date":    { "type": "date"    }
          }
        }
      }
    }
  }
}

在此之后,您可以从客户端重新索引数据,或者如果您希望零停机时间读取here

P.S:您必须在创建新映射之前删除特定索引的旧映射。