Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: build Mango indexes from dynamic expressions #3912

Open
wants to merge 6 commits into
base: 3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Prev Previous commit
Allow the /{db}/_index endpoint to accept jq definitions
We currently have to create jq-based indexes by writing out the whole
design document containing the Mango index definition, because the
`/{db}/_index` endpoint does not except anything except "asc" or "desc"
next to field names in the sort syntax.

Here we expand this to allow { "$jq": "..." } as well, letting us create
jq-based indexes without knowing the internal document format.

Even though internally we support mixing jq expressions with normal
field lookups in multi-field indexes, for now I'm restricting this so
that multi-field indexes have to either all use the same sort direction,
or all be jq expressions.
  • Loading branch information
jcoglan committed Jan 25, 2022
commit f5c661ee68c6929b2d69b15bea74c43b9e542b36
22 changes: 13 additions & 9 deletions src/mango/src/mango_sort.erl
Original file line number Diff line number Diff line change
Expand Up @@ -49,20 +49,24 @@ sort_field({[{Name, <<"asc">>}]}) when is_binary(Name) ->
{Name, <<"asc">>};
sort_field({[{Name, <<"desc">>}]}) when is_binary(Name) ->
{Name, <<"desc">>};
sort_field({[{Name, {[{<<"$jq">>, Expr}]} = Jq}]}) when is_binary(Name) and is_binary(Expr) ->
{Name, Jq};
sort_field({Name, BadDir}) when is_binary(Name) ->
?MANGO_ERROR({invalid_sort_dir, BadDir});
sort_field(Else) ->
?MANGO_ERROR({invalid_sort_field, Else}).

validate({Props}) ->
% Assert each field is in the same direction
% until we support mixed direction sorts.
Dirs = [D || {_, D} <- Props],
% Assert each field is in the same direction, or all fields are jq
% expressions, until we support mixed direction sorts.
Dirs = lists:map(fun(Prop) ->
case Prop of
{_, {[{<<"$jq">>, _}]}} -> jq;
{_, D} -> D
end
end, Props),
case lists:usort(Dirs) of
[] ->
ok;
[_] ->
ok;
_ ->
?MANGO_ERROR({unsupported, mixed_sort})
[] -> ok;
[_] -> ok;
_ -> ?MANGO_ERROR({unsupported, mixed_sort})
end.
40 changes: 9 additions & 31 deletions src/mango/test/22-index-function-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,22 @@
import mango


def create_index(db, ddoc_id, view_id, definition):
db.save_docs(
[
{
"_id": ddoc_id,
"language": "query",
"views": {
view_id: {
"map": {"fields": definition, "partial_filter_selector": {}},
"reduce": "_count",
"options": {"def": {"fields": definition}},
}
},
}
]
)


class IndexFunctionTests(mango.DbPerClass):
@classmethod
def setUpClass(klass):
super(IndexFunctionTests, klass).setUpClass()

create_index(
klass.db,
"_design/jq-split-1",
"jq-json-index",
{"f1_words": {"$jq": '.f1 | split(" ") | .[]'}},
klass.db.create_index(
[
{"f1_words": {"$jq": '.f1 | split(" ") | .[]'}},
]
)

create_index(
klass.db,
"_design/jq-split-2",
"jq-json-index",
{
"f2_words": {"$jq": '.f2 | split(" ") | .[]'},
"f3_words": {"$jq": '.f3 | split(" ") | .[]'},
},
klass.db.create_index(
[
{"f2_words": {"$jq": '.f2 | split(" ") | .[]'}},
{"f3_words": {"$jq": '.f3 | split(" ") | .[]'}},
],
)

klass.db.save_docs(
Expand Down