summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Newson <rnewson@apache.org>2020-06-22 18:24:25 +0100
committerGitHub <noreply@github.com>2020-06-22 18:24:25 +0100
commit22dbde22240c4a0ada2ee371adc8e8f01d99ac51 (patch)
tree8fb77bb2e24afebf50a0f1b87738e960b4601089
parent074789f20ffc65411d01d58a3d007cbae83bf58c (diff)
parent42403914a8c86a26cf58363f0eaf35551400aa30 (diff)
downloadcouchdb-prototype/fdn.tar.gz
Merge pull request #2958 from bessbd/allow-drilldown-list-of-listsarchive/prototype/fdnprototype/fdn
Allow drilldown for search to always be specified as list of lists
-rw-r--r--src/dreyfus/src/dreyfus_httpd.erl2
-rw-r--r--src/dreyfus/test/elixir/test/search_test.exs201
2 files changed, 203 insertions, 0 deletions
diff --git a/src/dreyfus/src/dreyfus_httpd.erl b/src/dreyfus/src/dreyfus_httpd.erl
index f0a130ef2..007dace8f 100644
--- a/src/dreyfus/src/dreyfus_httpd.erl
+++ b/src/dreyfus/src/dreyfus_httpd.erl
@@ -239,6 +239,8 @@ validate_index_query(counts, Value, Args) ->
Args#index_query_args{counts=Value};
validate_index_query(ranges, Value, Args) ->
Args#index_query_args{ranges=Value};
+validate_index_query(drilldown, [[_|_]|_] = Value, Args) ->
+ Args#index_query_args{drilldown=Value};
validate_index_query(drilldown, Value, Args) ->
DrillDown = Args#index_query_args.drilldown,
Args#index_query_args{drilldown=[Value|DrillDown]};
diff --git a/src/dreyfus/test/elixir/test/search_test.exs b/src/dreyfus/test/elixir/test/search_test.exs
new file mode 100644
index 000000000..e524a5cf4
--- /dev/null
+++ b/src/dreyfus/test/elixir/test/search_test.exs
@@ -0,0 +1,201 @@
+defmodule SearchTest do
+ use CouchTestCase
+
+ @moduletag :search
+
+ @moduledoc """
+ Test search
+ """
+
+ def create_search_docs(db_name) do
+ resp = Couch.post("/#{db_name}/_bulk_docs",
+ headers: ["Content-Type": "application/json"],
+ body: %{:docs => [
+ %{"item" => "apple", "place" => "kitchen", "state" => "new"},
+ %{"item" => "banana", "place" => "kitchen", "state" => "new"},
+ %{"item" => "carrot", "place" => "kitchen", "state" => "old"},
+ %{"item" => "date", "place" => "lobby", "state" => "unknown"},
+ ]}
+ )
+ assert resp.status_code in [201, 202]
+ end
+
+ def create_ddoc(db_name, opts \\ %{}) do
+ default_ddoc = %{
+ indexes: %{
+ fruits: %{
+ analyzer: %{name: "standard"},
+ 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}"
+ }
+ }
+ }
+
+ ddoc = Enum.into(opts, default_ddoc)
+
+ resp = Couch.put("/#{db_name}/_design/inventory", body: ddoc)
+ assert resp.status_code in [201, 202]
+ assert Map.has_key?(resp.body, "ok") == true
+ end
+
+ def get_items (resp) do
+ %{:body => %{"rows" => rows}} = resp
+ Enum.map(rows, fn row -> row["doc"]["item"] end)
+ end
+
+ @tag :with_db
+ test "search returns all items for GET", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.get(url, query: %{q: "*:*", include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
+ end
+
+ @tag :with_db
+ test "drilldown single key single value for GET", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode(["place", "kitchen"]), include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot"])
+ end
+
+ @tag :with_db
+ test "drilldown single key multiple values for GET", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode(["state", "new", "unknown"]), include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "date"])
+ end
+
+ @tag :with_db
+ test "drilldown multiple keys single values for GET", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.get(url, query: %{q: "*:*", drilldown: :jiffy.encode([["state", "old"], ["item", "apple"]]), include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == []
+ end
+
+ @tag :with_db
+ test "drilldown multiple query definitions for GET", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits?q=*:*&drilldown=[\"state\",\"old\"]&drilldown=[\"item\",\"apple\"]&include_docs=true"
+ resp = Couch.get(url)
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == []
+ end
+
+
+ @tag :with_db
+ test "search returns all items for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{q: "*:*", include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot", "date"])
+ end
+
+ @tag :with_db
+ test "drilldown single key single value for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{query: "*:*", drilldown: ["place", "kitchen"], include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "carrot"])
+ end
+
+ @tag :with_db
+ test "drilldown single key multiple values for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{query: "*:*", drilldown: ["state", "new", "unknown"], include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == Enum.sort(["apple", "banana", "date"])
+ end
+
+ @tag :with_db
+ test "drilldown multiple keys single values for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{q: "*:*", drilldown: [["state", "old"], ["item", "apple"]], include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == []
+ end
+
+ @tag :with_db
+ test "drilldown three keys single values for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{q: "*:*", drilldown: [["place", "kitchen"], ["state", "new"], ["item", "apple"]], include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == ["apple"]
+ end
+
+ @tag :with_db
+ test "drilldown multiple keys multiple values for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: %{q: "*:*", drilldown: [["state", "old", "new"], ["item", "apple"]], include_docs: true})
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == ["apple"]
+ end
+
+ @tag :with_db
+ test "drilldown multiple query definitions for POST", context do
+ db_name = context[:db_name]
+ create_search_docs(db_name)
+ create_ddoc(db_name)
+
+ url = "/#{db_name}/_design/inventory/_search/fruits"
+ resp = Couch.post(url, body: "{\"include_docs\": true, \"q\": \"*:*\", \"drilldown\": [\"state\", \"old\"], \"drilldown\": [\"item\", \"apple\"]}")
+ assert resp.status_code == 200
+ ids = get_items(resp)
+ assert Enum.sort(ids) == ["apple"]
+ end
+end