Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
265 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# this assumes Riak Search is enabled | ||
search-cmd set-schema tweets test/resources/search/tweets/schema.erl |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
(ns ^{:doc "Provides access to Riak Search via the Solr API. | ||
Only HTTP transport is supported."} | ||
clojurewerkz.welle.solr | ||
(:require [clojurewerkz.welle.core :as wc] | ||
[clj-http.client :as http] | ||
[cheshire.core :as json] | ||
[clojure.data.xml :as x]) | ||
(:import clojurewerkz.welle.HTTPClient)) | ||
|
||
;; | ||
;; Implementation | ||
;; | ||
|
||
(defn- get-base-solr-url | ||
"Returns base Sorl API URL (e.g. http://127.0.0.1:8098/solr)" | ||
([] | ||
(get-base-solr-url wc/*riak-client*)) | ||
([^HTTPClient client] | ||
(str (.getBaseUrl client) "/solr"))) | ||
|
||
(defn- get-solr-query-url | ||
"Returns Sorl query endpoint URL for the given index (e.g. http://127.0.0.1:8098/solr/production_index/select)" | ||
([^String index] | ||
(get-solr-query-url wc/*riak-client* index)) | ||
([^HTTPClient client ^String index] | ||
(str (get-base-solr-url wc/*riak-client*) "/" index "/select"))) | ||
|
||
(defn- get-solr-update-url | ||
"Returns Sorl update (index, delete, etc) endpoint URL for the given index (e.g. http://127.0.0.1:8098/solr/production_index/update)" | ||
([^String index] | ||
(get-solr-update-url wc/*riak-client* index)) | ||
([^HTTPClient client ^String index] | ||
(str (get-base-solr-url wc/*riak-client*) "/" index "/update"))) | ||
|
||
(defn- delete-via-query-body | ||
[^String query] | ||
(x/emit-str | ||
(x/element :delete {} | ||
(x/element :query {} query)))) | ||
|
||
(defn- ->xml-field | ||
[[k v]] | ||
(x/element :field {:name (name k)} (str v))) | ||
|
||
(defn- doc->xml-fields | ||
[m] | ||
(map ->xml-field m)) | ||
|
||
(defn- doc->xml | ||
[m] | ||
(x/element :doc {} | ||
(doc->xml-fields m))) | ||
|
||
(defn- as-vec | ||
[xs] | ||
(if (sequential? xs) | ||
xs | ||
[xs])) | ||
|
||
(defn- index-document-body | ||
[xs] | ||
(x/emit-str (x/element :add {} | ||
(map doc->xml (as-vec xs))))) | ||
|
||
(def ^{:const true} | ||
application-xml "application/xml") | ||
|
||
;; | ||
;; API | ||
;; | ||
|
||
(defn delete-via-query | ||
([^String query] | ||
(let [url (get-solr-update-url) | ||
{:keys [body]} (http/post url {:content-type application-xml :body (delete-via-query-body query)})] | ||
nil)) | ||
([^String index ^String query] | ||
(let [url (get-solr-update-url index) | ||
{:keys [body]} (http/post url {:content-type application-xml :body (delete-via-query-body query)})] | ||
;; looks like the response is always empty | ||
nil))) | ||
|
||
(defn index | ||
([doc] | ||
(let [url (get-solr-update-url) | ||
{:keys [body]} (http/post url {:content-type application-xml :body (index-document-body doc)})] | ||
doc)) | ||
([^String idx doc] | ||
(let [url (get-solr-update-url idx) | ||
{:keys [body]} (http/post url {:content-type application-xml :body (index-document-body doc)})] | ||
;; looks like the response is always empty | ||
doc))) | ||
|
||
(defn search | ||
[^String index ^String query & {:as options}] | ||
(let [url (get-solr-query-url index) | ||
qp (merge options {"wt" "json" "q" query}) | ||
{:keys [body]} (http/get url {:query-params qp})] | ||
(json/parse-string body true))) | ||
|
||
(defn search-across-all-indexes | ||
[^String query & {:as options}] | ||
(let [url (get-solr-query-url) | ||
qp (merge options {"wt" "json" "q" query}) | ||
{:keys [body]} (http/get url {:query-params qp})] | ||
(json/parse-string body true))) | ||
|
||
(defn total-hits | ||
[response] | ||
(get-in response [:response :numFound])) | ||
|
||
(defn any-hits? | ||
"Returns true if a response has any search hits, false otherwise" | ||
[response] | ||
(> (total-hits response) 0)) | ||
|
||
(def no-hits? (complement any-hits?)) | ||
|
||
(defn hits-from | ||
"Returns search hits from a response as a collection. To retrieve hits overview, get the :hits | ||
key from the response" | ||
[response] | ||
(get-in response [:response :docs])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package clojurewerkz.welle; | ||
|
||
import com.basho.riak.client.http.RiakClient; | ||
import com.basho.riak.client.http.RiakConfig; | ||
import com.basho.riak.client.raw.http.HTTPClientAdapter; | ||
|
||
/** | ||
* Just like {@link com.basho.riak.client.raw.http.HTTPClientAdapter} but exposes its configuration | ||
*/ | ||
public class HTTPClient extends HTTPClientAdapter { | ||
protected final RiakConfig config; | ||
|
||
public HTTPClient(RiakClient client) { | ||
super(client); | ||
this.config = client.getConfig(); | ||
} | ||
|
||
public RiakConfig getConfig() { | ||
return config; | ||
} | ||
|
||
public String getBaseUrl() { | ||
return config.getBaseUrl(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
(ns clojurewerkz.welle.test.search-test | ||
(:use clojure.test | ||
[clojurewerkz.welle.testkit :only [drain]]) | ||
(:require [clojurewerkz.welle.core :as wc] | ||
[clojurewerkz.welle.kv :as kv] | ||
[clojurewerkz.welle.buckets :as wb] | ||
[clojurewerkz.welle.solr :as wsolr]) | ||
(:import com.basho.riak.client.http.util.Constants)) | ||
|
||
(wc/connect!) | ||
|
||
(deftest ^{:search true} test-term-query-via-the-solr-api | ||
(let [bucket-name "clojurewerkz.welle.solr.tweets" | ||
bucket (wb/update bucket-name :last-write-wins true :enable-search true) | ||
doc {:username "clojurewerkz" | ||
:text "Elastisch beta3 is out, several more @elasticsearch features supported github.com/clojurewerkz/elastisch, improved docs http://clojureelasticsearch.info #clojure" | ||
:timestamp "20120802T101232+0100" | ||
:id 1}] | ||
(drain bucket-name) | ||
(kv/store bucket-name "a-key" doc :content-type "application/json") | ||
(let [result (wsolr/search bucket-name "username:clojurewerkz") | ||
hits (wsolr/hits-from result)] | ||
(is (= "a-key" (-> hits first :id))) | ||
(is (> (count hits) 0))) | ||
(drain bucket-name))) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "Alyssa P. Hacker", | ||
"username": "alyssa", | ||
"bio": "I'm an engineer, making awesome things.", | ||
"favorites":{ | ||
"book": "The Moon is a Harsh Mistress", | ||
"album": "Magical Mystery Tour" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"username": "clojurewerkz", | ||
"text": "Elastisch beta3 is out, several more @elasticsearch features supported github.com/clojurewerkz/elastisch, improved docs http://clojureelasticsearch.info #clojure", | ||
"timestamp": "20120802T101232+0100" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
%% an example used in Riak Handbook by Mathias Meyer, modified to fit Elastisch fixtures | ||
%% (we just take example documents from there) | ||
{schema, [{version, "1.1"}, | ||
{n_val, 2}, | ||
{default_field, "field"}, | ||
{default_op, "or"}, | ||
{analyzer_factory, {erlang, text_analyzers, whitespace_analyzer_factory}}], | ||
[{field, [{name, "text"}, | ||
{type, string}, | ||
{required, true}, | ||
{analyzer_factory, {erlang, text_analyzers, standard_analyzer_factory}}]}, | ||
{field, [{name, "timestamp"}, | ||
{type, date}, | ||
{required, true}, | ||
{analyzer_factory, {erlang, text_analyzers, noop_analyzer_factory}}]}, | ||
{field, [{name, "username"}, | ||
{type, string}, | ||
{required, true}, | ||
{analyzer_factory, {erlang, text_analyzers, noop_analyzer_factory}} ]}, | ||
{dynamic_field, [{name, "*"}, {skip, true}]} | ||
]}. |