Permalink
Browse files

very basic Riak Search usage

latest version of each article is tossed to Search, and requests for
pages that don't exist ask Search to look for pages containing the
words of the page title requested
  • Loading branch information...
1 parent 28ecba7 commit b084b39e46f82d5be1b416e92601053198b9c379 Bryan Fink committed Oct 4, 2010
@@ -242,6 +242,70 @@ render_404_editor(RD, Ctx) ->
to_html(RD, ACtx).
render_404(RD, Ctx) ->
+ Search = mochiweb_util:unquote(base64url:decode_to_string(search_path(RD))),
+ Results = search(Ctx#ctx.client, Search),
{ok, C} = error_404_dtl:render([{req, wrq_dtl_helper:new(RD)},
- {search, mochiweb_util:unquote(base64url:decode_to_string(search_path(RD)))}]),
+ {search, Search},
+ {results, Results}]),
{C, RD, Ctx}.
+
+-define(SEARCH_FUN,
+ iolist_to_binary(
+ [<<"function(v) {\n">>,
+ <<"return [v.key];\n">>,
+ <<"}">>])).
+
+search(Client, RawSearch) ->
+ case wriaki:search_enabled() of
+ true ->
+ Search = sanitize_search(RawSearch),
+ {ok, RawResults} =
+ wrc:mapred(Client,
+ {modfun, riak_search, mapred_search,
+ [<<"article">>,
+ iolist_to_binary([<<"text:">>, Search])]},
+ [{map, {jsanon, ?SEARCH_FUN}, <<>>, true}]),
+ case RawResults of
+ [{0, RawKeys}] ->
+ [ [{url, base64url:decode(R)},
+ {title, mochiweb_util:unquote(base64url:decode(R))}]
+ || R <- RawKeys ];
+ _ ->
+ []
+ end;
+ false ->
+ []
+ end.
+
+sanitize_search(RawSearch) ->
+ [ whitespace_search_operator(C) || C <- RawSearch ].
+
+whitespace_search_operator(C) ->
+ case is_search_operator(C) of
+ true -> 32; % space
+ false -> C
+ end.
+
+-define(SEARCH_OPERATORS,
+ [
+ $:,
+ $(,
+ $),
+ ${,
+ $},
+ $[,
+ $],
+ $+,
+ $-,
+ $!,
+ $&,
+ $|,
+ $^,
+ $~,
+ $*,
+ $?,
+ 34 % double quote "
+ ]).
+
+is_search_operator(C) ->
+ lists:member(C, ?SEARCH_OPERATORS).
View
@@ -20,15 +20,29 @@
-module(wriaki).
-export([set_bucket_props/0,
+ search_enabled/0,
get_app_env/2]).
-include_lib("wriaki.hrl").
set_bucket_props() ->
{ok, Client} = wrc:connect(),
- ok = wrc:set_bucket(Client, ?B_ARTICLE, [{allow_mult, true}]),
+ ok = wrc:set_bucket(Client, ?B_ARTICLE,
+ [{allow_mult, true}|search_hook()]),
ok = wrc:set_bucket(Client, ?B_HISTORY, [{allow_mult, true}]).
+search_hook() ->
+ case search_enabled() of
+ true ->
+ [{precommit, [{struct,[{<<"mod">>,<<"riak_search_kv_hook">>},
+ {<<"fun">>,<<"precommit">>}]}]}];
+ _ ->
+ []
+ end.
+
+search_enabled() ->
+ get_app_env(search_enabled, false) == true.
+
get_app_env(Env, Default) ->
case application:get_env(wriaki, Env) of
{ok, Val} -> Val;
@@ -38,7 +38,7 @@
<span class="wikiletter">i</span>
</a>
&nbsp;&nbsp;
- <input id="searchtext" value="{% if search %}{{ search }}{% endif %}" />
+ <input id="searchtext" value="{% if search %}{{ search|escape }}{% endif %}" />
<button id="searchbutton">go</button>
</div>
<div id="welcome">
@@ -24,5 +24,13 @@
<div class="notfound">
<h2>No page was found for &quot;{{ search|escape }}&quot;</h2>
<p>Would you like to <a href="/wiki/{{ search|escape }}?edit">create it</a>?</p>
+ {% if results %}
+ <h2>Perhaps you were looking for one of these pages?</h2>
+ <ul>
+ {% for result in results %}
+ <li><a href="/wiki/{{result.url}}">{{result.title|escape}}</li>
+ {% endfor %}
+ </ul>
+ {% endif%}
</div>
{% endblock %}
@@ -12,6 +12,9 @@
{riak, {pb, {"127.0.0.1", 8087}}},
% {riak, {http, {"127.0.0.1", 8098, "riak"}}},
+ %% Search functionality
+% {search_enabled, true},
+
%% Web interface settings
%% web_ip: what IP to listen on (0.0.0.0 = listen on all)
{web_ip, "0.0.0.0"},

0 comments on commit b084b39

Please sign in to comment.