我有这个有效的查询:
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
如何摆脱错误?
答案 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)