Elixir PostgreSQL - select 查询返回不符合 WHERE 子句的结果

Elixir PostgreSQL - select query returning results which do not conform to WHERE clause

我有这个功能select 我的数据库中的商店和他们的产品:

def create_unique_shop_query_no_keyword(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,
    distinct: s.id,
    where: c.id in ^categories,
    where: s.id in ^shop_ids,
    group_by: [s.id, s.name],
    select: %{products: fragment(
      "json_agg( DISTINCT (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)) AS products",
      p.id,
      p.name,
      p.brand,
      p.description,
      p.image,
      p.rating,
      p.number_of_votes,
      ps.not_in_shop_count,
      ps.is_in_shop_count,
      ps.price,
      p.not_vegan_count,
      p.vegan_count),
      shop: fragment(
        "json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?), ?, ?, ?, ?, ?)) AS shop",
        s.id,
        s.name,
        s.point,
        s.point,
        s.place_id,
        s.street,
        s.suburb,
        s.city,
        s.street_number
        )
      }
  end

我有另一个功能做同样的事情,但有一个关键词混在一起,它检查产品名称或产品品牌中的关键词(不一定是完整的词):

def create_unique_shop_query(keyword, 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,
    distinct: s.id,
    where: c.id in ^categories,
    where: s.id in ^shop_ids,
    where: like(p.name, ^("%#{keyword}%")),
    or_where: like(p.brand, ^("%#{keyword}%")),
    group_by: [s.id, s.name],
    select: %{products: fragment(
      "json_agg( DISTINCT (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)) AS products",
      p.id,
      p.name,
      p.brand,
      p.description,
      p.image,
      p.rating,
      p.number_of_votes,
      ps.not_in_shop_count,
      ps.is_in_shop_count,
      ps.price,
      p.not_vegan_count,
      p.vegan_count),
      shop: fragment(
        "json_agg( DISTINCT (?, ?, ST_X(?), ST_Y(?), ?, ?, ?, ?, ?)) AS shop",
        s.id,
        s.name,
        s.point,
        s.point,
        s.place_id,
        s.street,
        s.suburb,
        s.city,
        s.street_number
        )
      }
  end

没有关键字的 top 函数按预期工作。但是在有关键字的函数中,结果包含商店 ID (s.id) 不在 shop_ids 中的商店。这是为什么?

你有一个or_where,所以你的查询条件本质上是....

(c.id in categories) and (s.id in shop_ids) and (p.name like keyword) or (p.brand like keyword)

只要p.brand是关键字就匹配

这可能是您要查找的内容,将 OR 条件分组到 AND where 中以进行关键字匹配。

...
where: c.id in ^categories,
    where: s.id in ^shop_ids,
    where: like(p.name, ^("%#{keyword}%")) or like(p.brand, ^("%#{keyword}%")),
...

这将其转换为

(c.id in categories) and (s.id in shop_ids) and (p.name like keyword or p.brand like keyword)