|
diff --git a/src/mango/src/mango_cursor_view.erl b/src/mango/src/mango_cursor_view.erl |
|
index 68d7c3b62..88ffa8ba3 100644 |
|
--- a/src/mango/src/mango_cursor_view.erl |
|
+++ b/src/mango/src/mango_cursor_view.erl |
|
@@ -230,6 +230,8 @@ choose_best_index(_DbName, IndexRanges) -> |
|
{SelectedIndex, SelectedIndexRanges, _} = hd(lists:sort(Cmp, IndexRanges)), |
|
{SelectedIndex, SelectedIndexRanges}. |
|
|
|
+add_virtual_field({Props}, Key, [Value]) -> |
|
+ {lists:append(Props, [{Key, Value}])}. |
|
|
|
view_cb({meta, Meta}, Acc) -> |
|
% Map function starting |
|
@@ -238,9 +240,10 @@ view_cb({meta, Meta}, Acc) -> |
|
ok = rexi:stream2({meta, Meta}), |
|
{ok, Acc}; |
|
view_cb({row, Row}, #mrargs{extra = Options} = Acc) -> |
|
+ Key = couch_util:get_value(key, Row), |
|
ViewRow = #view_row{ |
|
id = couch_util:get_value(id, Row), |
|
- key = couch_util:get_value(key, Row), |
|
+ key = Key, |
|
doc = couch_util:get_value(doc, Row) |
|
}, |
|
case ViewRow#view_row.doc of |
|
@@ -254,9 +257,12 @@ view_cb({row, Row}, #mrargs{extra = Options} = Acc) -> |
|
put(mango_docs_examined, get(mango_docs_examined) + 1), |
|
Selector = couch_util:get_value(selector, Options), |
|
couch_stats:increment_counter([mango, docs_examined]), |
|
- case mango_selector:match(Selector, Doc) of |
|
+ {[{VirtualField, _}]} = Selector, |
|
+ Doc1 = add_virtual_field(Doc, VirtualField, Key), |
|
+ case mango_selector:match(Selector, Doc1) of |
|
true -> |
|
- ok = rexi:stream2(ViewRow), |
|
+ ViewRow1 =ViewRow#view_row{doc = Doc1}, |
|
+ ok = rexi:stream2(ViewRow1), |
|
set_mango_msg_timestamp(); |
|
false -> |
|
maybe_send_mango_ping() |
|
diff --git a/src/mango/src/mango_doc.erl b/src/mango/src/mango_doc.erl |
|
index c22b15544..2038359f9 100644 |
|
--- a/src/mango/src/mango_doc.erl |
|
+++ b/src/mango/src/mango_doc.erl |
|
@@ -22,6 +22,7 @@ |
|
|
|
get_field/2, |
|
get_field/3, |
|
+ get_field_fun/2, |
|
rem_field/2, |
|
set_field/3 |
|
]). |
|
@@ -408,6 +409,19 @@ get_field(Values, [Name | Rest], Validator) when is_list(Values) -> |
|
get_field(_, [_|_], _) -> |
|
bad_path. |
|
|
|
+get_field_fun(Props, MangoFun) -> |
|
+ {FunName, {Args}} = MangoFun, |
|
+ case FunName of |
|
+ <<"$explode">> -> handle_explode(Props, Args); |
|
+ _ -> bad_path |
|
+ end. |
|
+ |
|
+handle_explode({Doc}, Args) -> |
|
+ FieldName = proplists:get_value(<<"$field">>, Args), |
|
+ Separator = proplists:get_value(<<"$separator">>, Args), |
|
+ {_, FieldValue} = lists:keyfind(FieldName, 1, Doc), |
|
+ R = string:split(FieldValue, Separator, all), |
|
+ {fn, R}. |
|
|
|
rem_field(Props, Field) when is_binary(Field) -> |
|
{ok, Path} = mango_util:parse_field(Field), |
|
diff --git a/src/mango/src/mango_native_proc.erl b/src/mango/src/mango_native_proc.erl |
|
index 274ae11de..df0418bc6 100644 |
|
--- a/src/mango/src/mango_native_proc.erl |
|
+++ b/src/mango/src/mango_native_proc.erl |
|
@@ -146,13 +146,21 @@ get_index_entries({IdxProps}, Doc) -> |
|
Values = get_index_values(Fields, Doc), |
|
case lists:member(not_found, Values) of |
|
true -> []; |
|
- false -> [[Values, null]] |
|
+ false -> case Values of |
|
+ [{fn, Values1}] -> lists:map(fun(V) -> [[V], null] end, Values1); |
|
+ _Else -> [[Values, null]] |
|
+ end |
|
end |
|
end. |
|
|
|
- |
|
get_index_values(Fields, Doc) -> |
|
- lists:map(fun({Field, _Dir}) -> |
|
+ lists:map(fun({_Field, {[MangoFun]}}) -> |
|
+ case mango_doc:get_field_fun(Doc, MangoFun) of |
|
+ not_found -> not_found; |
|
+ bad_path -> not_found; |
|
+ Value -> Value |
|
+ end; |
|
+ ({Field, _Dir}) -> |
|
case mango_doc:get_field(Doc, Field) of |
|
not_found -> not_found; |
|
bad_path -> not_found; |