Skip to content

Instantly share code, notes, and snippets.

@blinkov
Created April 3, 2012 12:44
Show Gist options
  • Save blinkov/2291683 to your computer and use it in GitHub Desktop.
Save blinkov/2291683 to your computer and use it in GitHub Desktop.
Riak Solr Client
-module(riak_solr_client).
-author("Ivan Blinkov <ivan@blinkov.ru>").
%% WARNING: Not yet tested in production, use with care.
%%
%% This module provides access to sort and limit/offset features of Riak
%% accessible only via Solr interface.
%%
%% Supposed to be used with conjunction with:
%% https://github.com/basho/riak-erlang-client
%%
%% Dependencies:
%% - https://github.com/davisp/jiffy
%% - https://github.com/esl/lhttpc
-export(search/4, search/5).
-type bucket() :: binary().
-type key() :: binary() | 'undefined'.
-type vclock() :: binary().
-type metadata() :: dict().
-type content_type() :: string().
-type value() :: binary().
-type contents() :: [{metadata(), value()}].
-record(riakc_obj, {
bucket :: bucket(),
key :: key(),
vclock :: vclock(),
contents :: contents(),
updatemetadata :: dict(),
updatevalue :: value()
}).
-define(RIAK_HOST, "127.0.0.1").
-define(SOLR_PORT, 8098).
-spec search(Bucket :: string(), SearchQuery :: string(),
Sort :: string(), Page :: integer()) -> [#riakc_obj{}].
search(Bucket, SearchQuery, Sort, Page) ->
search(Bucket, SearchQuery, Sort, Page, 10).
-spec search(Bucket :: string(), SearchQuery :: string(),
Sort :: string(), Page :: integer(), PageSize :: integer()) -> [#riakc_obj{}].
search(Bucket, SearchQuery, Sort, Page, PageSize) ->
Start = (Page - 1) * PageSize,
Path = "/solr/" ++ Bucket ++ "/select?wt=json&start="
++ integer_to_list(Start) ++ "&rows=" ++ integer_to_list(PageSize)
++ "&sort=" ++ Sort ++ "&q=" ++ re:replace(SearchQuery, "\s", "%20", [global, {return, list}]),
case lhttpc:request(?RIAK_HOST, ?SOLR_PORT,
false, Path, 'GET', [], <<>>, 30000, []) of
{ok, {{200,"OK"}, _Headers, QueryResponse}} ->
{[{<<"responseHeader">>,_}, {<<"response">>, Response}]} = jiffy:decode(QueryResponse),
{[_, _, _, {<<"docs">>, Docs}]} = Response,
lists:map(fun wrap_search_results/1, Docs);
[] ->
[]
end.
-spec field_to_propvalue(Tuple :: tuple()) -> [#riakc_obj{}].
wrap_search_results(Tuple) ->
{[{<<"id">>, Key},
{<<"index">>, Bucket},
{<<"fields">>, {Fields}},
{<<"props">>,_}]} = Tuple,
#riakc_obj{bucket = Bucket, key = Key, contents = [],
updatevalue = lists:map(fun field_to_propvalue/1, Fields)}.
-spec field_to_propvalue(Field :: tuple()) -> tuple().
field_to_propvalue(Field) ->
{Key, Value} = Field,
{list_to_atom(binary_to_list(Key)), Value}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment