Разобрать ответ elasticsearch в RestClient

Я пишу приложение Rails 3, используя Datamapper в качестве ORM. Я рассматриваю возможность использования ElasticSearch для поиска, но не могу использовать жемчужину Tire, поскольку она, похоже, зависит от ActiveRecord.

Я использую RestClient для отправки запросов в ElasticSearch, но у меня возникают проблемы с анализом ответа в ruby.

Если я отправляю запрос GET "http://localhost:9200/twitter/tweet/2", я получаю в браузере следующее:

{
  "_index": "twitter",
  "_type": "tweet",
  "_id": "2",
  "_version": 3,
  "exists": true,
  "_source": {
    "user": "kimchy",
    "post_date": "2009-11-15T14:12:12",
    "message": "kimchy kimchy says"
  }
}

В Rails, когда я набираю следующее:

response = RestClient.get 'http://localhost:9200/twitter/tweet/2',{:content_type => :json, :accept => :json}

Я получаю этот результат:

{
  "_index": "twitter",
  "_type": "tweet",
  "_id": "2",
  "_version": 3,
  "exists": true,
  "_source": {
    "user": "kimchy",
    "post_date": "2009-11-15T14:12:12",
    "message": "kimchy kimchy says"
  }
}

Это выглядит правильно, но я не могу получить данные, используя точечную запись, как обычно с JSON.

Например, я не могу написать response._type, так как получаю ошибку неопределенного метода.

Очень ценю любую помощь в этом!


person Gerard    schedule 03.05.2012    source источник
comment
Tire не зависит от ActiveRecord, но зависит от ActiveModel. Если DataMapper предоставляет интерфейс, совместимый с ActiveModel, вы должны быть отсортированы.   -  person karmi    schedule 04.05.2012


Ответы (2)


Если вы хотите выполнить преобразование вручную, вы можете проанализировать ответ из json и вручную преобразовать его в объект для доступа к полям с точечной нотацией.

Что-то вроде этого:

require 'json'
require 'ostruct'

response = RestClient.get '...url...'
o = OpenStruct.new(JSON.parse(response))

Затем вы сможете получить доступ к полям с помощью o._type или o.message.

person thnetos    schedule 09.05.2012

Возможно, более широкий ответ, чем то, что вы ищете…

Я использую что-то вроде этот смысл для переноса вызовов RestClient в ElasticSearch. Он анализирует выходные данные JSON и спасает некоторые исключения RestClient, чтобы также анализировать и передавать выходные данные сервера в клиентский код.

Вот сокращенная версия для вас:

# url and method are provided as a param
options = { url: '...', method: '...' }

# default options
options = {
  headers: {
    accept:       :json,
    content_type: :json
  },
  open_timeout: 1,
  timeout:      1
}

begin
  request  = RestClient::Request.new(options)
  response = request.execute
  JSON.parse(response.to_str)

rescue RestClient::BadRequest => e # and others...
  # log e.message
  JSON.parse(e.response.to_str)
end

В итоге вы получите хэш, полученный из ответа ElasticSearch в формате JSON.

То, как все это взаимодействует с DataMapper, немного выходит за рамки моего обычного опыта, но не стесняйтесь уточнять или задавать дополнительные вопросы в комментариях.

person Nick Zadrozny    schedule 09.05.2012