address review comments
diff --git a/nouveau/README.md b/nouveau/README.md
index e0c9636..86b1914 100644
--- a/nouveau/README.md
+++ b/nouveau/README.md
@@ -49,7 +49,7 @@
`make`
-Run Nouvea with;
+Run Nouveau with;
`dev/run --admin=foo:bar --with-nouveau`
@@ -87,7 +87,7 @@
This will cause Nouveau to build indexes for each copy (N) and each
shard range (Q) and then perform a search and return the results. Lots
of query syntax is working as is sorting on strings and numbers
-(`sort=["fieldnamehere<string>"] or sort=["fieldnamehere<number>"],
+(`sort=["fieldnamehere<string>"] or sort=["fieldnamehere<number>"`],
defaulting to number).
Facet support
diff --git a/nouveau/TODO b/nouveau/TODO
index 4e81404..f43343a 100644
--- a/nouveau/TODO
+++ b/nouveau/TODO
@@ -1,27 +1,8 @@
targeted dreyfus feature parity
-* pagination (bookmark I guess)
-* grouping
-* faceting
-* partitioned db support
-* ken integration
-* delete indexes on db deletion
+* partitioned db support (partially done)
not targeted
-* stale=ok
* highlighting
* drilldown
-
-After reaching dreyfus parity, nouveau will diverge;
-
-* no javascript eval
-* ddoc will require an index schema, mapping couchdb document fields to lucene fields
-* spatial-extras and spatial3d support
-
-interim ideas
-
-* append type to field name, so `index("foo", 12.0")` becomes `new DoublePoint("foo<number>", 12.0)`
-* set a special Map to setPointsConfigMap() which examines that suffix and returns a PointsConfig for <number>
-
-* in nouveau branch of couchdb, remove dreyfus entirely and put nouveau at _search_analyze, _search,
\ No newline at end of file
diff --git a/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java b/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java
index e0d0ea6..ddc7c3f 100644
--- a/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java
+++ b/nouveau/src/main/java/org/apache/couchdb/nouveau/core/IndexManager.java
@@ -105,7 +105,7 @@
scheduler.execute(() -> {
if (index.tryAcquire()) {
try {
- LOGGER.info("committing {}", name);
+ LOGGER.debug("committing {}", name);
try {
index.commit();
} catch (final IOException e) {
@@ -301,7 +301,7 @@
if (index.tryAcquire()) {
try {
if (!index.isDeleteOnClose() && index.commit()) {
- LOGGER.info("committed {} before close", name);
+ LOGGER.debug("committed {} before close", name);
}
} finally {
index.release();
diff --git a/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java b/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
index 8f9e26c..4273582 100644
--- a/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
+++ b/nouveau/src/main/java/org/apache/couchdb/nouveau/resources/IndexResource.java
@@ -16,6 +16,7 @@
import java.io.IOException;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import org.apache.couchdb.nouveau.api.DocumentDeleteRequest;
import org.apache.couchdb.nouveau.api.DocumentUpdateRequest;
@@ -64,8 +65,8 @@
private final SearcherFactory searcherFactory;
public IndexResource(final IndexManager indexManager, final SearcherFactory searcherFactory) {
- this.indexManager = indexManager;
- this.searcherFactory = searcherFactory;
+ this.indexManager = Objects.requireNonNull(indexManager);
+ this.searcherFactory = Objects.requireNonNull(searcherFactory);
}
@PUT
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini
index ede5e84..14b2a53 100644
--- a/rel/overlay/etc/default.ini
+++ b/rel/overlay/etc/default.ini
@@ -809,7 +809,7 @@
; The name and location of the Clouseau Java service required to
; enable Search functionality.
;name = clouseau@127.0.0.1
-name={{clouseau_name}}
+name = {{clouseau_name}}
; CouchDB will try to re-connect to Clouseau using a bounded
; exponential backoff with the following number of iterations.
diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl
index b308061..7223ce4 100644
--- a/src/chttpd/src/chttpd.erl
+++ b/src/chttpd/src/chttpd.erl
@@ -1129,7 +1129,7 @@
"request due to overloading or maintenance mode."
>>};
error_info({internal_server_error, Reason}) ->
- {500, <<"internal server error">>, Reason};
+ {500, <<"internal_server_error">>, Reason};
error_info(not_implemented) ->
{501, <<"not_implemented">>, <<"this feature is not yet implemented">>};
error_info(timeout) ->
diff --git a/src/nouveau/src/nouveau_api.erl b/src/nouveau/src/nouveau_api.erl
index 99139a9..5bf6b17 100644
--- a/src/nouveau/src/nouveau_api.erl
+++ b/src/nouveau/src/nouveau_api.erl
@@ -35,7 +35,7 @@
->
ReqBody = {[{<<"text">>, Text}, {<<"analyzer">>, Analyzer}]},
Resp = send_if_enabled(
- io_lib:format("~s/analyze", [nouveau_util:nouveau_url()]),
+ nouveau_util:nouveau_url() ++ "/analyze",
[?JSON_CONTENT_TYPE],
post,
jiffy:encode(ReqBody)
diff --git a/src/nouveau/src/nouveau_bookmark.erl b/src/nouveau/src/nouveau_bookmark.erl
index 0721d5a..b919534 100644
--- a/src/nouveau/src/nouveau_bookmark.erl
+++ b/src/nouveau/src/nouveau_bookmark.erl
@@ -28,10 +28,10 @@
update(DbName, {EJson}, SearchResults) when is_list(EJson) ->
update(DbName, from_ejson({EJson}), SearchResults);
update(DbName, PreviousBookmark, SearchResults) when is_map(PreviousBookmark) ->
- Hits = maps:get(<<"hits">>, SearchResults),
+ #{<<"hits">> := Hits} = SearchResults,
NewBookmark0 = lists:foldl(
- fun(Hit, Acc) ->
- maps:put(range_of(DbName, maps:get(<<"id">>, Hit)), maps:get(<<"order">>, Hit), Acc)
+ fun(#{<<"id">> := Id, <<"order">> := Order}, Acc) ->
+ Acc#{range_of(DbName, Id) => Order}
end,
new(),
Hits
diff --git a/src/nouveau/src/nouveau_fabric_search.erl b/src/nouveau/src/nouveau_fabric_search.erl
index 6f428e8..2aeb502 100644
--- a/src/nouveau/src/nouveau_fabric_search.erl
+++ b/src/nouveau/src/nouveau_fabric_search.erl
@@ -37,8 +37,9 @@
go(DbName, #doc{} = DDoc, IndexName, QueryArgs0) ->
{ok, Index} = nouveau_util:design_doc_to_index(DbName, DDoc, IndexName),
Shards = mem3:shards(DbName),
- Bookmark = nouveau_bookmark:unpack(DbName, maps:get(bookmark, QueryArgs0)),
- QueryArgs1 = maps:remove(bookmark, QueryArgs0),
+ {PackedBookmark, #{limit := Limit, sort := Sort} = QueryArgs1} =
+ maps:take(bookmark, QueryArgs0),
+ Bookmark = nouveau_bookmark:unpack(DbName, PackedBookmark),
Counters0 = lists:map(
fun(#shard{} = Shard) ->
After = maps:get(Shard#shard.range, Bookmark, null),
@@ -54,13 +55,19 @@
Workers = fabric_dict:fetch_keys(Counters),
RexiMon = fabric_util:create_monitors(Workers),
State = #state{
- limit = maps:get(limit, QueryArgs0),
- sort = maps:get(sort, QueryArgs0),
+ limit = Limit,
+ sort = Sort,
counters = Counters,
search_results = #{}
},
try
- rexi_utils:recv(Workers, #shard.ref, fun handle_message/3, State, infinity, 1000 * 60 * 60)
+ rexi_utils:recv(
+ Workers,
+ #shard.ref,
+ fun handle_message/3,
+ State,
+ fabric_util:timeout("nouveau", "infinity"),
+ fabric_util:timeout("nouveau_permsg", "3600000"))
of
{ok, SearchResults} ->
NewBookmark = nouveau_bookmark:update(DbName, Bookmark, SearchResults),
diff --git a/test/elixir/test/config/nouveau.elixir b/test/elixir/test/config/nouveau.elixir
index d22cf6f..90390a9 100644
--- a/test/elixir/test/config/nouveau.elixir
+++ b/test/elixir/test/config/nouveau.elixir
@@ -1,5 +1,7 @@
%{
"NouveauTest": [
+ "search analyze",
+ "search info",
"search returns all items for GET",
"search returns all items for POST",
"search returns all items (paginated)",
diff --git a/test/elixir/test/nouveau_test.exs b/test/elixir/test/nouveau_test.exs
index 06fcc42..ee5d205 100644
--- a/test/elixir/test/nouveau_test.exs
+++ b/test/elixir/test/nouveau_test.exs
@@ -52,6 +52,35 @@
bookmark
end
+ test "search analyze", context do
+ url = "/_nouveau_analyze"
+ resp = Couch.post(url,
+ headers: ["Content-Type": "application/json"],
+ body: %{analyzer: "standard", text: "hello there"})
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+ assert resp.body == %{"tokens" => ["hello", "there"]}
+ end
+
+ @tag :with_db
+ test "search info", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ # query it so it builds
+ url = "/#{db_name}/_design/foo/_nouveau/bar"
+ resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+
+ url = "/#{db_name}/_design/foo/_nouveau_info/bar"
+ resp = Couch.get(url)
+ assert resp.status_code == 200, "error #{resp.status_code} #{:jiffy.encode(resp.body)}"
+ info = Map.get(resp.body, "search_index")
+ assert Map.get(info, "disk_size") > 0
+ assert Map.get(info, "num_docs") > 0
+ assert Map.get(info, "update_seq") > 0
+ end
+
@tag :with_db
test "search returns all items for GET", context do
db_name = context[:db_name]