defmodule Noizu.Weaviate.GraphQL.Additional do
defmodule Classification do
defstruct [
properties: []
]
def classification(properties) do
properties = (is_list(properties) && properties || [properties])
|> Enum.filter(fn(p) -> p in [:id, :classified_fields, :based_on, :completed, :scope] end)
unless properties == [] do
%__MODULE__{
properties: properties
}
end
end
defimpl Jason.Encoder do
@lookup %{
id: "id",
scope: "scope",
completed: "completed",
based_on: "basedOn",
classified_fields: "classifiedFields"
}
def encode(this, opts) do
properties = Enum.map(this.properties, &(@lookup[&1]))
|> Enum.join("\n ")
encoded = """
classification {
#{properties}
}
""" |> String.trim()
end
end
end
defmodule FeatureProjection do
defstruct [
dimensions: 2,
algorithm: nil,
perplexity: nil,
learning_rate: nil,
iterations: nil,
properties: [:vector]
]
def feature_projection(options) do
%__MODULE__{
dimensions: options[:dimensions] || 2,
algorithm: options[:algorithm],
perplexity: options[:perplexity],
learning_rate: options[:learning_rate],
iterations: options[:iterations]
}
end
defimpl Jason.Encoder do
@lookup %{
vector: "vector",
}
def encode(this, opts) do
properties = Enum.map(this.properties, &(@lookup[&1]))
|> Enum.join("\n ")
options =
[]
|> then(& this.dimensions && [{:dimensions, this.dimensions}|&1] || &1 )
|> then(& this.algorithm && [{:algorithm, this.algorithm}|&1] || &1 )
|> then(& this.perplexity && [{:perplexity, this.perplexity}|&1] || &1 )
|> then(& this.learning_rate && [{:learningRate, this.learning_rate}|&1] || &1 )
|> then(& this.iterations && [{:iterations, this.iterations}|&1] || &1 )
|> Enum.map(fn({k,v}) -> "#{k}: #{inspect v}" end)
|> Enum.join(", ")
encoded = """
featureProjection(#{options}) {
#{properties}
}
""" |> String.trim()
end
end
end
defmodule Answer do
defstruct []
defimpl Jason.Encoder do
def encode(_this, _opts) do
"""
answer {
hasAnswer
result
certainty
property
startPosition
endPosition
}
""" |> String.trim()
end
end
end
defmodule Generate do
defstruct [
single_result_prompt: nil,
grouped_result_task: nil,
grouped_result_properties: nil
]
defimpl Jason.Encoder do
def encode(this, _opts) do
options =
[]
|> then(& this.single_result_prompt && [{:singleResult, %{prompt: this.single_result_prompt}}|&1] || &1 )
|> then(& this.grouped_result_task && [{:groupedResult, %{task: this.grouped_result_task, properties: this.grouped_result_properties}}|&1] || &1 )
options_str = Enum.map(options, fn
{:singleResult, %{prompt: prompt}} -> "singleResult: { prompt: #{inspect prompt} }"
{:groupedResult, %{task: task, properties: nil}} -> "groupedResult: { task: #{inspect task} }"
{:groupedResult, %{task: task, properties: props}} ->
props_str = Enum.map(props, &inspect/1) |> Enum.join(", ")
"groupedResult: { task: #{inspect task}, properties: [#{props_str}] }"
end)
|> Enum.join("\n ")
"""
generate(
#{options_str}
) {
singleResult
groupedResult
error
}
""" |> String.trim()
end
end
end
defmodule Rerank do
defstruct [
property: nil,
query: nil
]
defimpl Jason.Encoder do
def encode(this, _opts) do
options =
[]
|> then(& this.property && [{:property, this.property}|&1] || &1 )
|> then(& this.query && [{:query, this.query}|&1] || &1 )
|> Enum.map(fn({k,v}) -> "#{k}: #{inspect v}" end)
|> Enum.join(", ")
"""
rerank(#{options}) {
score
}
""" |> String.trim()
end
end
end
defmodule Summary do
defstruct [
properties: []
]
defimpl Jason.Encoder do
def encode(this, _opts) do
props_str = Enum.map(this.properties, &inspect/1) |> Enum.join(", ")
"""
summary(properties: [#{props_str}]) {
property
result
}
""" |> String.trim()
end
end
end
defmodule Tokens do
defstruct [
properties: [],
certainty: nil,
limit: nil
]
defimpl Jason.Encoder do
def encode(this, _opts) do
props_str = Enum.map(this.properties, &inspect/1) |> Enum.join(", ")
options =
[{:properties, "[#{props_str}]"}]
|> then(& this.certainty && [{:certainty, this.certainty}|&1] || &1 )
|> then(& this.limit && [{:limit, this.limit}|&1] || &1 )
|> Enum.reverse()
|> Enum.map(fn
{:properties, v} -> "properties: #{v}"
{k, v} -> "#{k}: #{v}"
end)
|> Enum.join(", ")
"""
tokens(#{options}) {
entity
word
property
certainty
startPosition
endPosition
}
""" |> String.trim()
end
end
end
defmodule Group do
defstruct [
hit_properties: [],
hit_additional: []
]
defimpl Jason.Encoder do
def encode(this, _opts) do
hit_props = Enum.join(this.hit_properties, "\n ")
hit_additional = case this.hit_additional do
[] -> ""
additional ->
adds = Enum.join(additional, "\n ")
"\n _additional { #{adds} }"
end
hits_block = case {this.hit_properties, this.hit_additional} do
{[], []} -> ""
_ ->
"""
hits {
#{hit_props}#{hit_additional}
}
""" |> String.trim_trailing()
end
"""
group {
id
groupedBy { value path }
count
maxDistance
minDistance
#{hits_block}
}
""" |> String.trim()
end
end
end
defmodule Vectors do
defstruct [
names: []
]
defimpl Jason.Encoder do
def encode(this, _opts) do
names_str = Enum.join(this.names, "\n ")
"""
vectors {
#{names_str}
}
""" |> String.trim()
end
end
end
defstruct [
properties: [],
]
def additional(properties) do
properties = cond do
is_list(properties) -> properties
:else -> [properties]
end
%__MODULE__{properties: properties}
end
defimpl Jason.Encoder do
@lookup %{
id: "id",
vector: "vector",
generate: "generate",
rerank: "rerank",
creation_time: "creationTimeUnix",
last_update_time: "lastUpdateTimeUnix",
distance: "distance",
certainty: "certainty",
score: "score",
explain_score: "explainScore",
is_consistent: "isConsistent",
}
def encode(this, opts) do
contents = Enum.map(this.properties,
fn
(property) when property in [:id, :vector, :generate, :rerank, :creation_time, :last_update_time, :distance, :certainty, :score, :explain_score, :is_consistent] -> @lookup[property]
(property = %FeatureProjection{}) -> Jason.encode!(property)
(property = %Classification{}) -> Jason.encode!(property)
(property = %Answer{}) -> Jason.encode!(property)
(property = %Generate{}) -> Jason.encode!(property)
(property = %Rerank{}) -> Jason.encode!(property)
(property = %Summary{}) -> Jason.encode!(property)
(property = %Tokens{}) -> Jason.encode!(property)
(property = %Group{}) -> Jason.encode!(property)
(property = %Vectors{}) -> Jason.encode!(property)
(_) -> nil
end)
|> Enum.reject(&is_nil/1)
|> Enum.join("\n ")
"""
_additional {
#{contents}
}
""" |> String.trim()
end
end
end