diff options
author | Garren Smith <garren.smith@gmail.com> | 2018-06-18 14:50:27 +0200 |
---|---|---|
committer | Garren Smith <garren.smith@gmail.com> | 2018-06-18 14:52:05 +0200 |
commit | de8c6e1d65665bd68c78ef31f80e82c1f046a9b9 (patch) | |
tree | d8aaebb525964c53c92d22f332f6d05538e14c3d | |
parent | 65d4d9563fc4945f10fd258e9617ade4a1ed707a (diff) | |
download | couchdb-de8c6e1d65665bd68c78ef31f80e82c1f046a9b9.tar.gz |
Move sort filtering into is_usable
-rw-r--r-- | src/mango/src/mango_cursor.erl | 18 | ||||
-rw-r--r-- | src/mango/src/mango_idx.erl | 27 | ||||
-rw-r--r-- | src/mango/src/mango_idx_special.erl | 15 | ||||
-rw-r--r-- | src/mango/src/mango_idx_text.erl | 13 | ||||
-rw-r--r-- | src/mango/src/mango_idx_view.erl | 15 | ||||
-rw-r--r-- | src/mango/test/18-json-sort.py | 14 | ||||
-rw-r--r-- | src/mango/test/mango.py | 1 |
7 files changed, 47 insertions, 56 deletions
diff --git a/src/mango/src/mango_cursor.erl b/src/mango/src/mango_cursor.erl index 5108d36b2..5d2ea717d 100644 --- a/src/mango/src/mango_cursor.erl +++ b/src/mango/src/mango_cursor.erl @@ -48,18 +48,12 @@ create(Db, Selector0, Opts) -> Selector = mango_selector:normalize(Selector0), UsableIndexes = mango_idx:get_usable_indexes(Db, Selector, Opts), - case length(UsableIndexes) of - 0 -> - AllDocs = mango_idx:special(Db), - create_cursor(Db, AllDocs, Selector, Opts); - _ -> - case mango_cursor:maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of - [] -> - % use_index doesn't match a valid index - fall back to a valid one - create_cursor(Db, UsableIndexes, Selector, Opts); - UserSpecifiedIndex -> - create_cursor(Db, UserSpecifiedIndex, Selector, Opts) - end + case mango_cursor:maybe_filter_indexes_by_ddoc(UsableIndexes, Opts) of + [] -> + % use_index doesn't match a valid index - fall back to a valid one + create_cursor(Db, UsableIndexes, Selector, Opts); + UserSpecifiedIndex -> + create_cursor(Db, UserSpecifiedIndex, Selector, Opts) end. diff --git a/src/mango/src/mango_idx.erl b/src/mango/src/mango_idx.erl index 7c37585c7..211edacf4 100644 --- a/src/mango/src/mango_idx.erl +++ b/src/mango/src/mango_idx.erl @@ -66,13 +66,12 @@ get_usable_indexes(Db, Selector, Opts) -> SortFields = get_sort_fields(Opts), UsableFilter = fun(I) -> is_usable(I, Selector, SortFields) end, - UsableIndexes1 = lists:filter(UsableFilter, UsableIndexes0), - case maybe_filter_by_sort_fields(UsableIndexes1, Selector, SortFields) of - {ok, SortIndexes} -> - SortIndexes; - {error, no_usable_index} -> - ?MANGO_ERROR({no_usable_index, missing_sort_index}) + case lists:filter(UsableFilter, UsableIndexes0) of + [] -> + ?MANGO_ERROR({no_usable_index, missing_sort_index}); + UsableIndexes1 -> + UsableIndexes1 end. @@ -100,22 +99,6 @@ get_sort_fields(Opts) -> end. -maybe_filter_by_sort_fields(Indexes, _Selector, []) -> - {ok, Indexes}; - -maybe_filter_by_sort_fields(Indexes, Selector, SortFields) -> - FilterFun = fun(Idx) -> - Mod = idx_mod(Idx), - Mod:maybe_filter_by_sort_fields(Idx, SortFields, Selector) - end, - case lists:filter(FilterFun, Indexes) of - [] -> - {error, no_usable_index}; - FilteredIndexes -> - {ok, FilteredIndexes} - end. - - new(Db, Opts) -> Def = get_idx_def(Opts), Type = get_idx_type(Opts), diff --git a/src/mango/src/mango_idx_special.erl b/src/mango/src/mango_idx_special.erl index a2869ad8e..aa1ec2f41 100644 --- a/src/mango/src/mango_idx_special.erl +++ b/src/mango/src/mango_idx_special.erl @@ -65,9 +65,11 @@ columns(#idx{def=all_docs}) -> [<<"_id">>]. -is_usable(#idx{def=all_docs}, Selector, _) -> +is_usable(#idx{def=all_docs}, _Selector, []) -> + true; +is_usable(#idx{def=all_docs} = Idx, Selector, SortFields) -> Fields = mango_idx_view:indexable_fields(Selector), - lists:member(<<"_id">>, Fields). + lists:member(<<"_id">>, Fields) and maybe_filter_by_sort_fields(Idx, SortFields, Selector). start_key([{'$gt', Key, _, _}]) -> @@ -100,6 +102,13 @@ end_key([{'$eq', Key, '$eq', Key}]) -> Key. +% maybe_filter_by_sort_fields(Idx, SortFields, Selector) -> +% Cols = columns(Idx), +% io:format("HERE BOOM ~p ~n ~p ~n", [Idx, Cols]), +% lists:prefix(SortFields, Cols). + +maybe_filter_by_sort_fields(_Idx, [], _Selector) -> + true; maybe_filter_by_sort_fields(Idx, SortFields, _Selector) -> - Cols = mango_idx:columns(Idx), + Cols = columns(Idx), lists:prefix(SortFields, Cols). diff --git a/src/mango/src/mango_idx_text.erl b/src/mango/src/mango_idx_text.erl index 6e4f0350b..29b4441a1 100644 --- a/src/mango/src/mango_idx_text.erl +++ b/src/mango/src/mango_idx_text.erl @@ -23,8 +23,7 @@ to_json/1, columns/1, is_usable/3, - get_default_field_options/1, - maybe_filter_by_sort_fields/3 + get_default_field_options/1 ]). @@ -377,16 +376,6 @@ forbid_index_all() -> config:get("mango", "index_all_disabled", "false"). -maybe_filter_by_sort_fields(Idx, SortFields, _Selector) -> - Cols = mango_idx:columns(Idx), - case Cols of - all_fields -> - true; - _ -> - sets:is_subset(sets:from_list(SortFields), sets:from_list(Cols)) - end. - - -ifdef(TEST). -include_lib("eunit/include/eunit.hrl"). diff --git a/src/mango/src/mango_idx_view.erl b/src/mango/src/mango_idx_view.erl index fe4549e34..db3c5eb15 100644 --- a/src/mango/src/mango_idx_view.erl +++ b/src/mango/src/mango_idx_view.erl @@ -24,7 +24,6 @@ columns/1, start_key/1, end_key/1, - maybe_filter_by_sort_fields/3, indexable_fields/1, field_ranges/1, @@ -132,7 +131,8 @@ is_usable(Idx, Selector, SortFields) -> [<<"_id">>, <<"_rev">>]), mango_selector:has_required_fields(Selector, RequiredFields2) - andalso not is_text_search(Selector). + andalso not is_text_search(Selector) + andalso can_use_sort(RequiredFields, SortFields, Selector). is_text_search({[]}) -> @@ -514,11 +514,12 @@ range_pos(Low, Arg, High) -> end. -maybe_filter_by_sort_fields(Idx, SortFields, Selector) -> - Cols = mango_idx:columns(Idx), +can_use_sort(_Cols, [], _Selector) -> + true; +can_use_sort(Cols, SortFields, Selector) -> case lists:subtract(SortFields, Cols) of [] -> - NormalizedSortFields = normalize_sort_fields(Cols, SortFields, Selector), + NormalizedSortFields = add_constant_sort_fields(Cols, SortFields, Selector), lists:prefix(NormalizedSortFields, Cols); _ -> false @@ -526,7 +527,7 @@ maybe_filter_by_sort_fields(Idx, SortFields, Selector) -> % This is an user experience improvement. If a selector has a sort field set -% then an index is only valid if the prefix of the sort fields match the +% then an index is only valid if the sort fields match the % prefix of the index fields. % e.g Index = [A, B, C] with Sort = [A, B] is a valid sort @@ -541,7 +542,7 @@ maybe_filter_by_sort_fields(Idx, SortFields, Selector) -> % The sort will work as expected and this will increase the possibility % of the index being choosen. It also helps a user where they might not have % put correct initial fields in the sort. -normalize_sort_fields(Cols, SortFields, Selector) -> +add_constant_sort_fields(Cols, SortFields, Selector) -> lists:foldr(fun (Col, Sort) -> case lists:member(Col, SortFields) of true -> diff --git a/src/mango/test/18-json-sort.py b/src/mango/test/18-json-sort.py index 58ace485c..6c5db4880 100644 --- a/src/mango/test/18-json-sort.py +++ b/src/mango/test/18-json-sort.py @@ -154,6 +154,20 @@ class JSONIndexSortOptimisations(mango.DbPerClass): resp = e.response.json() self.assertEqual(resp["error"], "no_usable_index") + def test_empty_sort(self): + self.db.create_index(["cars", "age", "name"], name="cars-age-name") + selector = { + "name": { + "$gt": "Eddie", + }, + "age": 10, + "cars": { + "$gt": "1" + } + } + explain = self.db.find(selector, explain=True) + self.assertEqual(explain["index"]["name"], "cars-age-name") + def test_in_between(self): self.db.create_index(["cars", "age", "name"], name="cars-age-name") selector = { diff --git a/src/mango/test/mango.py b/src/mango/test/mango.py index 9b6b998cd..13873211a 100644 --- a/src/mango/test/mango.py +++ b/src/mango/test/mango.py @@ -240,6 +240,7 @@ class Database(object): else: path = self.path("_find") r = self.sess.post(path, data=body) + print r.json() r.raise_for_status() if explain or return_raw: return r.json() |