summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2023-03-28 13:01:35 +0100
committerRobert Newson <rnewson@apache.org>2023-03-28 14:43:17 +0100
commitc156313335005341d62d3e8d73f72137e9369d09 (patch)
treef4feb890e49b8cf1ce140f3ddae19ddd632dd9f6
parent7e393d69f8e07a2a40a85bfcab17f8d6dfc5acb5 (diff)
downloadcouchdb-c156313335005341d62d3e8d73f72137e9369d09.tar.gz
include_docs=true support
-rw-r--r--nouveau/server/README.md1
-rw-r--r--src/nouveau/src/nouveau_fabric.erl8
-rw-r--r--src/nouveau/src/nouveau_httpd.erl22
-rw-r--r--test/elixir/test/nouveau_test.exs4
4 files changed, 27 insertions, 8 deletions
diff --git a/nouveau/server/README.md b/nouveau/server/README.md
index 944f6b707..d8c5a5adc 100644
--- a/nouveau/server/README.md
+++ b/nouveau/server/README.md
@@ -18,7 +18,6 @@ Nouveau is an experimental search extension for CouchDB 3.x.
## What doesn't work yet?
-* include_docs=true
* POST support for _nouveau
* No support for results grouping
* No support to configure stop words for analyzers
diff --git a/src/nouveau/src/nouveau_fabric.erl b/src/nouveau/src/nouveau_fabric.erl
index 511cf073c..9056b60ee 100644
--- a/src/nouveau/src/nouveau_fabric.erl
+++ b/src/nouveau/src/nouveau_fabric.erl
@@ -27,11 +27,11 @@ callback({meta, _}, Acc) ->
callback({error, Reason}, _Acc) ->
{error, Reason};
callback({row, Row}, Acc) ->
- case lists:keyfind(value, 1, Row) of
- {value, not_found} ->
+ case lists:keyfind(doc, 1, Row) of
+ false ->
{ok, [not_found | Acc]};
- {value, _} ->
- {ok, [lists:keyfind(doc, 1, Row) | Acc]}
+ {doc, Doc} ->
+ {ok, [Doc | Acc]}
end;
callback(complete, Acc) ->
{ok, lists:reverse(Acc)};
diff --git a/src/nouveau/src/nouveau_httpd.erl b/src/nouveau/src/nouveau_httpd.erl
index 9e24fbb4d..7f028d2b3 100644
--- a/src/nouveau/src/nouveau_httpd.erl
+++ b/src/nouveau/src/nouveau_httpd.erl
@@ -52,6 +52,7 @@ handle_search_req(#httpd{method = 'GET', path_parts = [_, _, _, _, IndexName]} =
Counts = ?JSON_DECODE(chttpd:qs_value(Req, "counts", "null")),
Update = chttpd:qs_value(Req, "update", "true"),
Bookmark = chttpd:qs_value(Req, "bookmark"),
+ IncludeDocs = parse_bool_param("include_docs", chttpd:qs_value(Req, "include_docs", "false")),
QueryArgs = #{
query => Query,
limit => Limit,
@@ -67,7 +68,9 @@ handle_search_req(#httpd{method = 'GET', path_parts = [_, _, _, _, IndexName]} =
<<"bookmark">> => nouveau_bookmark:pack(maps:get(bookmark, SearchResults)),
<<"total_rows">> => maps:get(<<"total_hits">>, SearchResults),
<<"total_rows_relation">> => maps:get(<<"total_hits_relation">>, SearchResults),
- <<"rows">> => maps:get(<<"hits">>, SearchResults),
+ <<"rows">> => include_docs(
+ DbName, maps:get(<<"hits">>, SearchResults), IncludeDocs
+ ),
<<"counts">> => maps:get(<<"counts">>, SearchResults, null),
<<"ranges">> => maps:get(<<"ranges">>, SearchResults, null)
},
@@ -82,6 +85,23 @@ handle_info_req(_Req, _Db, _DDoc) ->
check_if_enabled(),
ok.
+include_docs(_DbName, Hits, false) ->
+ Hits;
+include_docs(DbName, Hits, true) ->
+ Ids = [maps:get(<<"id">>, Hit) || Hit <- Hits],
+ {ok, Docs} = nouveau_fabric:get_json_docs(DbName, Ids),
+ lists:zipwith(fun(Hit, Doc) -> Hit#{<<"doc">> => Doc} end, Hits, Docs).
+
+parse_bool_param(_, Val) when is_boolean(Val) ->
+ Val;
+parse_bool_param(_, "true") ->
+ true;
+parse_bool_param(_, "false") ->
+ false;
+parse_bool_param(Name, Val) ->
+ Msg = io_lib:format("Invalid value for ~s: ~p", [Name, Val]),
+ throw({query_parse_error, ?l2b(Msg)}).
+
check_if_enabled() ->
case nouveau:enabled() of
true ->
diff --git a/test/elixir/test/nouveau_test.exs b/test/elixir/test/nouveau_test.exs
index 2c49fe61c..56d44ee10 100644
--- a/test/elixir/test/nouveau_test.exs
+++ b/test/elixir/test/nouveau_test.exs
@@ -26,7 +26,7 @@ defmodule NouveauTest do
fruits: %{
default_analyzer: "standard",
lucene_major: 9,
- index: "function (doc) {\n index(\"item\", doc.item, {store: true, facet: true});\n index(\"place\", doc.place, {facet: true});\n index(\"state\", doc.state, {facet: true});\n}"
+ index: "function (doc) {\n index(\"item\", doc.item, {facet: true});\n index(\"place\", doc.place, {facet: true});\n index(\"state\", doc.state, {facet: true});\n}"
}
}
}
@@ -54,7 +54,7 @@ defmodule NouveauTest do
def get_items (resp) do
%{:body => %{"rows" => rows}} = resp
- Enum.map(rows, fn row -> row["fields"]["item"] end)
+ Enum.map(rows, fn row -> row["doc"]["item"] end)
end
@tag :with_db