当前位置: 首页 > 面试题库 >

ElasticSearch返回的搜索结果中包括不在映射中的字段

巴学潞
2023-03-14
问题内容

我想使用Tire gem作为ElasticSearch的客户端来索引pdf附件。在我的映射中,我从_source中排除了附件字段,因此附件不存储在索引中,
也不在搜索结果中返回

mapping :_source => { :excludes => ['attachment_original'] } do
  indexes :id, :type => 'integer'
  indexes :folder_id, :type => 'integer'
  indexes :attachment_file_name
  indexes :attachment_updated_at, :type => 'date'
  indexes :attachment_original, :type => 'attachment'
end

运行以下curl命令时,仍然可以看到搜索结果中包含的附件​​内容:

curl -X POST "http://localhost:9200/user_files/user_file/_search?pretty=true" -d '{
  "query": {
    "query_string": {
      "query": "rspec"
    }
  }
}'

我已经在这个线程中发布了我的问题:

但是我刚刚注意到,不仅附件包含在搜索结果中,而且所有其他字段(包括未映射的字段)也都包含在内,如下所示:

{
  "took": 20,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.025427073,
    "hits": [
      {
        "_index": "user_files",
        "_type": "user_file",
        "_id": "5",
        "_score": 0.025427073,
        "_source": {
          "user_file": {
            "id": 5,
            "folder_id": 1,
            "updated_at": "2012-08-16T11:32:41Z",
            "attachment_file_size": 179895,
            "attachment_updated_at": "2012-08-16T11:32:41Z",
            "attachment_file_name": "hw4.pdf",
            "attachment_content_type": "application/pdf",
            "created_at": "2012-08-16T11:32:41Z",
            "attachment_original": "JVBERi0xLjQKJeLjz9MKNyA"
          }
        }
      }
    ]
  }
}

attachment_file_size并且attachment_content_type未在映射中定义,而是在搜索结果中返回:

{
  "id": 5,
  "folder_id": 1,
  "updated_at": "2012-08-16T11:32:41Z",
  "attachment_file_size": 179895, <---------------------
  "attachment_updated_at": "2012-08-16T11:32:41Z",
  "attachment_file_name": "hw4.pdf", <------------------
  "attachment_content_type": "application/pdf",
  "created_at": "2012-08-16T11:32:41Z",
  "attachment_original": "JVBERi0xLjQKJeLjz9MKNyA"
}

这是我的完整实现:

  include Tire::Model::Search
  include Tire::Model::Callbacks

  def self.search(folder, params)
    tire.search() do
      query { string params[:query], default_operator: "AND"} if params[:query].present?
      #filter :term, folder_id: folder.id
      #highlight :attachment_original, :options => {:tag => "<em>"}
      raise to_curl
    end
  end

  mapping :_source => { :excludes => ['attachment_original'] } do
    indexes :id, :type => 'integer'
    indexes :folder_id, :type => 'integer'
    indexes :attachment_file_name
    indexes :attachment_updated_at, :type => 'date'
    indexes :attachment_original, :type => 'attachment'
  end

  def to_indexed_json
     to_json(:methods => [:attachment_original])
   end

  def attachment_original
    if attachment_file_name.present?
      path_to_original = attachment.path
      Base64.encode64(open(path_to_original) { |f| f.read })
    end    
  end

有人可以帮我弄清楚为什么所有字段都包含在中_source吗?

编辑: 这是运行的输出localhost:9200/user_files/_mapping

{
  "user_files": {
    "user_file": {
      "_source": {
        "excludes": [
          "attachment_original"
        ]
      },
      "properties": {
        "attachment_content_type": {
          "type": "string"
        },
        "attachment_file_name": {
          "type": "string"
        },
        "attachment_file_size": {
          "type": "long"
        },
        "attachment_original": {
          "type": "attachment",
          "path": "full",
          "fields": {
            "attachment_original": {
              "type": "string"
            },
            "author": {
              "type": "string"
            },
            "title": {
              "type": "string"
            },
            "name": {
              "type": "string"
            },
            "date": {
              "type": "date",
              "format": "dateOptionalTime"
            },
            "keywords": {
              "type": "string"
            },
            "content_type": {
              "type": "string"
            }
          }
        },
        "attachment_updated_at": {
          "type": "date",
          "format": "dateOptionalTime"
        },
        "created_at": {
          "type": "date",
          "format": "dateOptionalTime"
        },
        "folder_id": {
          "type": "integer"
        },
        "id": {
          "type": "integer"
        },
        "updated_at": {
          "type": "date",
          "format": "dateOptionalTime"
        }
      }
    }
  }
}

如您所见,由于某些原因,所有字段都包含在映射中!


问题答案:

在您的中to_indexed_json,您包含了attachment_original方法,因此将其发送给elasticsearch。这也是为什么所有其他属性都包含在映射中并因此包含在源中的原因。

有关该主题的更多信息,请参见ElasticSearch&Tire:使用映射和to_indexed_json问题。

似乎Tire确实确实在将正确的映射JSON发送到elasticsearch -我的建议是使用Tire.configure { logger STDERR,level: "debug" }来检查正在发生的事情,并使用trz在原始级别上查明问题。



 类似资料:
  • 我正在用Hibernate Search 4.5.1和Spring 4.0.5版本构建一个应用程序。我正在尝试索引以下类: 我正在构建一个junit测试用例,看起来如下所示: 我还注意到在luke lucene上,一些索引词的长度最多为6个字符,例如,一首歌的艺术家是“后代”,而索引中存储的词是“the”和“offspr”。第一个可以,但第二个不应该是“后代”。为什么要截断名字?

  • 问题内容: 我有一个运行中的elasticsearch的内存实例,并做了一些探索性的编码来学习搜索Java API。我能够将文档提交到索引并使用GET检索它们,但是当我尝试简单的搜索查询时,没有得到任何结果。 经过一些测试后,我认为问题出在我如何设置节点和关联的客户端(在内存中): 问题答案: Googleelasticsearch小组中的某个人很友好,可以在这里帮助我。将文档提交到内存节点后,我

  • 我有三个索引,它们都共享一个特定的键值对。当我用api进行全面搜索时”http://localhost:9200/_search“使用请求正文 它只返回其中两个索引的结果。我尝试使用相同的请求正文,将url更改为仅在丢失的索引中搜索”http://localhost:9200/index_name/_search“这很管用。我有什么遗漏吗? 插入所有三个索引的代码遵循相同的过程,我使用elasti

  • 问题内容: 我正在尝试在ElasticSearch中运行类似的字段查询: 意思是我正在尝试查找所有文档,其中产品名称在这种情况下是’milk’的子字符串。 我该怎么做? 问题答案: 我会使用一个使用ngrams的自定义分析器。首先创建一个像这样的索引: 然后,您可以索引一些数据: 最后,您可以像这样搜索: 然后您将获得前两个文档,

  • 我试图在ElasticSearch中运行类似的字段查询:

  • 问题内容: 简而言之,当不使用_geo_distance排序时,是否有一种方法可以返回地理距离? 更新:为澄清起见,我希望结果按随机顺序排列并包含距离。 问题答案: 是的,您可以使用脚本字段。 例如,假设您的文档具有一个名为的地理位置字段,则可以使用以下内容: (请注意,只是一个转义的单引号,所以真的是) 如果还希望返回该字段,则可以如下指定: