具有导致"的函数的where子句不是有效的查询表达式"

时间:2017-05-30 22:16:32

标签: elixir ecto elixir-framework

我有这个有效的查询:

  products_shops_categories = from p in Product,
  join: ps in ProductShop, on: p.id == ps.p_id,
  join: s in Shop, on: s.id == ps.s_id,
  join: pc in ProductCategory, on: p.id == pc.p_id,
  join: c in Subcategory, on: c.id == pc.c_id,
  where: c.id in ^categories,
  where: s.id in ^shop_ids,
  select: [p, c, s]

我只想添加一个where子句,以便考虑keywords。如果用户输入了一些关键字,则只有在关键字位于产品名称或产品品牌中时才返回产品。

我的尝试:

def are_keywords_in_product(keywords, product) do
  IO.inspect(product)
  Enum.map(keywords, fn(keyword) -> 
    product.name =~ keyword || product.brand =~ keyword
  end)
end

def create_query(keywords, categories, shop_ids) do
  products_shops_categories = from p in Product,
  join: ps in ProductShop, on: p.id == ps.p_id,
  join: s in Shop, on: s.id == ps.s_id,
  join: pc in ProductCategory, on: p.id == pc.p_id,
  join: c in Subcategory, on: c.id == pc.c_id,
  where: c.id in ^categories,
  where: s.id in ^shop_ids,
  where: are_keywords_in_product(keywords, p), 
  select: [p, c, s]
end

def create_query(nil, categories, shop_ids) do
  products_shops_categories = from p in Product,
  join: ps in ProductShop, on: p.id == ps.p_id,
  join: s in Shop, on: s.id == ps.s_id,
  join: pc in ProductCategory, on: p.id == pc.p_id,
  join: c in Subcategory, on: c.id == pc.c_id,
  where: c.id in ^categories,
  where: s.id in ^shop_ids,
  select: [p, c, s]
end

    ......create_query(keywords, categories, shop_ids) |> Api.Repo.all

如果关键字位于产品名称或品牌中,where中的create_query(keywords)条款实际上应该返回true(如果产品中找不到关键字,我可能需要尝试返回false而不是false ?)。

我收到此错误:

== Compilation error on file lib/api/router.ex ==
** (Ecto.Query.CompileError) `are_keywords_in_product(keywords, p)` is not a valid query expression.

* If you intended to call a database function, please check the documentation
  for Ecto.Query to see the supported database expressions

* If you intended to call an Elixir function or introduce a value,
  you need to explicitly interpolate it with ^

    expanding macro: Ecto.Query.where/3
    lib/api/router.ex:169: Api.Router.create_query/3
    expanding macro: Ecto.Query.select/3
    lib/api/router.ex:169: Api.Router.create_query/3
    expanding macro: Ecto.Query.from/2
    lib/api/router.ex:169: Api.Router.create_query/3

如何摆脱错误?

1 个答案:

答案 0 :(得分:0)

哦,我看到现在正在做什么are_keywords_in_product,我不确定Ecto是否支持开箱即用。我认为你最好的选择是为自己写一个fragment代替。

下面的代码只是一个起点。实际上没有写出正确的SQL查询。

的内容
def are_keywords_in_product(keywords) do
  Enum.map(keywords, fn(keyword) -> 
    "(?) =~" <> keyword <> " || (?) =~ " keyword
  end) |> Enum.join("")
end

并在查询中

where: fragment(^(are_keyswords_in_product(keywords)), variables)