diff options
author | Robert Newson <rnewson@apache.org> | 2023-03-28 13:01:35 +0100 |
---|---|---|
committer | Robert Newson <rnewson@apache.org> | 2023-03-28 14:43:17 +0100 |
commit | c156313335005341d62d3e8d73f72137e9369d09 (patch) | |
tree | f4feb890e49b8cf1ce140f3ddae19ddd632dd9f6 | |
parent | 7e393d69f8e07a2a40a85bfcab17f8d6dfc5acb5 (diff) | |
download | couchdb-c156313335005341d62d3e8d73f72137e9369d09.tar.gz |
include_docs=true support
-rw-r--r-- | nouveau/server/README.md | 1 | ||||
-rw-r--r-- | src/nouveau/src/nouveau_fabric.erl | 8 | ||||
-rw-r--r-- | src/nouveau/src/nouveau_httpd.erl | 22 | ||||
-rw-r--r-- | test/elixir/test/nouveau_test.exs | 4 |
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 |