mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-02-17 11:04:22 +01:00
parser
This commit is contained in:
parent
2f350791e6
commit
fe69b708db
2 changed files with 60 additions and 12 deletions
|
@ -259,8 +259,15 @@ defmodule Philomena.Search.Lexer do
|
||||||
gte
|
gte
|
||||||
])
|
])
|
||||||
|
|
||||||
boost = ignore(string("^")) |> unwrap_and_tag(number, :boost)
|
boost =
|
||||||
fuzz = ignore(string("~")) |> unwrap_and_tag(number, :fuzz)
|
string("^")
|
||||||
|
|> unwrap_and_tag(:boost)
|
||||||
|
|> concat(number)
|
||||||
|
|
||||||
|
fuzz =
|
||||||
|
string("~")
|
||||||
|
|> unwrap_and_tag(:fuzz)
|
||||||
|
|> concat(number)
|
||||||
|
|
||||||
quot = string("\"")
|
quot = string("\"")
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ defmodule Philomena.Search.Parser do
|
||||||
|
|
||||||
defp search_boost(ctx, tokens) do
|
defp search_boost(ctx, tokens) do
|
||||||
case search_not(ctx, tokens) do
|
case search_not(ctx, tokens) do
|
||||||
{child, [{:boost, _}, {:float, value} | r_tokens]} ->
|
{child, [{:boost, _}, {:number, value} | r_tokens]} ->
|
||||||
{%{function_score: %{query: child, boost_factor: value}}, r_tokens}
|
{%{function_score: %{query: child, boost_factor: value}}, r_tokens}
|
||||||
|
|
||||||
{child, rest} ->
|
{child, rest} ->
|
||||||
|
@ -92,23 +92,64 @@ defmodule Philomena.Search.Parser do
|
||||||
defp search_group(ctx, tokens), do: search_fuzz(ctx, tokens)
|
defp search_group(ctx, tokens), do: search_fuzz(ctx, tokens)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Term fuzzing
|
# Terms and term fuzzing
|
||||||
#
|
#
|
||||||
|
|
||||||
defp search_fuzz(ctx, tokens) do
|
defp search_fuzz(%{default_field: default_field} = ctx, tokens) do
|
||||||
search_term(ctx, tokens)
|
case tokens do
|
||||||
|
[{:int_field, field}, {:eq, _}, {:int, value}, {:fuzz, _}, {:number, fuzz} | r_tokens] ->
|
||||||
|
{%{range: %{field => %{gte: trunc(value - fuzz), lte: trunc(value + fuzz)}}}, r_tokens}
|
||||||
|
[{:float_field, field}, {:eq, _}, {:float, value}, {:fuzz, _}, {:number, fuzz} | r_tokens] ->
|
||||||
|
{%{range: %{field => %{gte: trunc(value - fuzz), lte: trunc(value + fuzz)}}}, r_tokens}
|
||||||
|
[{:literal_field, field}, {:eq, _}, {:text, value}, {:fuzz, _}, {:number, fuzz} | r_tokens] ->
|
||||||
|
{%{fuzzy: %{field => %{value: value, fuzziness: fuzz}}}, r_tokens}
|
||||||
|
[{:ngram_field, field}, {:eq, _}, {:text, value}, {:fuzz, _}, {:number, fuzz} | r_tokens] ->
|
||||||
|
{%{fuzzy: %{field => %{value: value, fuzziness: fuzz}}}, r_tokens}
|
||||||
|
[{:default, [text: value]}, {:fuzz, _}, {:number, fuzz} | r_tokens] ->
|
||||||
|
{%{fuzzy: %{default_field => %{value: value, fuzziness: fuzz}}}, r_tokens}
|
||||||
|
_ ->
|
||||||
|
search_range(ctx, tokens)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Search terms
|
# Range queries
|
||||||
#
|
#
|
||||||
|
|
||||||
defp search_term(_ctx, [{:term, _t} | rest]) do
|
defp search_range(ctx, tokens) do
|
||||||
{[], rest}
|
case tokens do
|
||||||
|
[{:int_field, field}, {range, _}, {:int, value} | r_tokens] when range in [:gt, :gte, :lt, :lte] ->
|
||||||
|
{%{range: %{field => %{range => value}}}, r_tokens}
|
||||||
|
[{:float_field, field}, {range, _}, {:float, value} | r_tokens] when range in [:gt, :gte, :lt, :lte] ->
|
||||||
|
{%{range: %{field => %{range => value}}}, r_tokens}
|
||||||
|
[{:date_field, field}, {range, _}, {:date, [lower, _higher]} | r_tokens] when range in [:gt, :gte, :lt, :lte] ->
|
||||||
|
{%{range: %{field => %{range => lower}}}, r_tokens}
|
||||||
|
_ ->
|
||||||
|
search_custom(ctx, tokens)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp search_term(_ctx, []), do: raise(ArgumentError, "Expected a term, got <end of input>.")
|
defp search_custom(ctx, tokens) do
|
||||||
|
case tokens do
|
||||||
|
[{:custom_field, field}, {:text, value} | r_tokens] ->
|
||||||
|
{ctx[:field_transforms][field].(value), r_tokens}
|
||||||
|
_ ->
|
||||||
|
search_term(ctx, tokens)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp search_term(_ctx, [{_, text} | _rest]),
|
defp search_term(ctx, tokens) do
|
||||||
do: raise(ArgumentError, "Expected a term, got `#{text}'.")
|
case tokens do
|
||||||
|
[{:date_field, field}, {:eq, _}, {:date, [lower, higher]} | r_tokens] ->
|
||||||
|
{%{range: %{field => %{gte: lower, lte: higher}}}, r_tokens}
|
||||||
|
[{:ngram_field, field}, {:eq, _}, {:text, value} | r_tokens] ->
|
||||||
|
{%{match: %{field => value}}, r_tokens}
|
||||||
|
[{_field_type, field}, {:eq, _}, {_value_type, value} | r_tokens] ->
|
||||||
|
{%{term: %{field => value}}, r_tokens}
|
||||||
|
[{:default, [text: value]} | r_tokens] ->
|
||||||
|
{%{term: %{ctx[:default_field] => value}}, r_tokens}
|
||||||
|
_ ->
|
||||||
|
raise ArgumentError, "Expected a term"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue