如何基于字段列表动态构建带ilike与类型转换的Ecto查询
动态构建Ecto多字段ILike查询
你可以通过Enum.reduce遍历字段列表,逐步构建包含多个OR条件的查询,每个条件将字段转为text类型并使用ILIKE匹配搜索词。以下是修正后的完整实现:
def lookup(search_term) do fields = [:id, :title, :body] # 给搜索词添加前后通配符,实现模糊匹配 like_pattern = "%#{search_term}%" query = from p in Post, where: build_query(p, fields, like_pattern), select: p Repo.all(query) end defp build_query(queryable, fields, like_pattern) do # 用Enum.reduce累加OR条件,初始值设为false,第一个条件直接替换初始值 Enum.reduce(fields, false, fn field, acc -> field_condition = fragment("CAST(? AS text) ILIKE ?", field(queryable, ^field), ^like_pattern) if acc, do: dynamic([], ^acc or ^field_condition), else: field_condition end) end
关键说明:
- 通配符处理:给搜索词加上
%,实现前后模糊匹配,符合ILIKE的常用场景。 - Enum.reduce初始值:设为
false,确保第一个字段条件直接作为初始查询条件,后续字段用OR连接。 - dynamic/2宏:用于动态组合查询条件,避免Ecto查询编译时的语法问题,确保条件能正确累加。
- field/2函数:通过
field(queryable, ^field)动态获取查询实体的字段,保证字段引用的正确性。
内容的提问来源于stack exchange,提问作者Billbryson78
相关产品推荐
相关产品推荐

