2017-05-30 31 views
0

我有這個工作查詢:凡與功能造成條款「是不是有效的查詢表達式」

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。 EG如果用戶輸入了一些關鍵字,只有在關鍵字處於產品名稱或產品品牌中時才返回產品。

我嘗試:

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 

有效,如果關鍵字在產品名稱或品牌我在create_query(keywords)最後where條款應返回true(我可能需要嘗試和回報,而不是什麼錯誤,如果關鍵字不在產品中找到?)。

我得到這個錯誤:

== 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

我認爲你需要做的^東西(are_keywords_in_product(關鍵字,P)) – jonzlin95

+0

@ jonzlin95它說'未定義函數P/0'。因此,似乎「p」的論點不被評估爲產品。我也嘗試過'^(are_keywords_in_product(keywords,^ p))',它說'不能在匹配子句外使用^ p' – BeniaminoBaggins

回答

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) 
相關問題