日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Elixir Ecto: 范围数据类型

發布時間:2023/12/4 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Elixir Ecto: 范围数据类型 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

PostgreSQL 9.2 以來, 可以用特定的操作符和函數存儲和查詢一個值的范圍. 這是一個非常不錯的特性, 比如在電子商務應用程序方面, 可以用一個字段 price_range 來替代 min_price, max_price 表示一個價格范圍.

在Ecto中使用范圍數據類型

價格范圍的表示方法如下

[0, 45.67] [30.04, 98.50] [100, 500]

我們可以用范圍操作符來查詢一個值的范圍

2.5 <@ numrange(1.50,7)

Postgresql 支持如下范圍類型

  • int4range?整數方位

  • int8range?—?大整數范圍

  • numrange?—?十進制數字范圍(浮點)

  • tsrange?—?不帶時區的時間戳范圍

  • tstzrange?—?帶時區的時間戳范圍

  • daterange?—?日期范圍

Ecto 本身為了兼容各個數據庫, 并沒有支持Postgresql 特有的Range數據類型, 但Ecto為我們提供了一個自定義數據類型的方法. 下面我們創建一個 NumRange 類型, 底層用了Postgrex適配器的%Postgrex.Range{}結構

defmodule App.NumRange do @behaviour Ecto.Typedef type, do: :numrangedef cast([lower, upper]) do{:ok, [lower, upper]}enddef cast(_), do: :errordef load(%Postgrex.Range{lower: lower, upper: nil}) do{lower, _} = lower |> to_float{:ok, [lower, nil]}enddef load(%Postgrex.Range{lower: lower, upper: upper}) do{lower, _} = lower |> to_float{upper, _} = upper |> to_float{:ok, [lower, upper]}enddef dump([lower, upper]) do{:ok, %Postgrex.Range{lower: lower, upper: upper, upper_inclusive: false}}enddef dump(_), do: :errordefp to_float(value) dovalue |> Decimal.to_string |> Float.parseend end

在模型和遷移腳本中中使用這個自定義數據類型

模型

defmodule App.Product do use App.Web, :modelschema "products" dofield :price_range, App.NumRangetimestampsend end

遷移腳本

defmodule App.Repo.Migrations.Product do use Ecto.Migrationdef change docreate table(:products) doadd :price_range, :numrangetimestampsendend end

范圍查詢

defmodule App.ProductQuery do import Ecto.Queryalias App.{Repo, Product}def within_price_range(price) doquery =from p in Product,where: fragment("?::numeric <@ ?", ^price, p.price_range)query |> Repo.allend end

關于方位邊界的問題, 和數學中的范圍符號是一樣的:

  • [ 包括下邊界

  • ( 不包括下邊界

  • ] 包括上邊界

  • ) 不包括上邊界

例子

# 創建表 create table products(id int, price_range numrange); # 插入數據 INSERT INTO products VALUES(1, '[10.0, 100.0]') INSERT INTO products VALUES(1, '[200.0, 300.0]') INSERT INTO products VALUES(1, '[400.0, 500.0]') INSERT INTO products VALUES(1, '[600.0, 700.0]') # 查詢 SELECT * FROM products; +------+--------------------------------------------------------+ | id | price_range | |------+--------------------------------------------------------| | 1 | NumericRange(Decimal('10.0'), Decimal('100.0'), '[]') | | 1 | NumericRange(Decimal('200.0'), Decimal('300.0'), '[]') | | 1 | NumericRange(Decimal('400.0'), Decimal('500.0'), '[]') | | 1 | NumericRange(Decimal('600.0'), Decimal('700.0'), '[]') | +------+--------------------------------------------------------+ # 過濾 SELECT * FROM products WHERE price_range::numrange @> 99.0 +------+-------------------------------------------------------+ | id | price_range | |------+-------------------------------------------------------| | 1 | NumericRange(Decimal('10.0'), Decimal('100.0'), '[]') | +------+-------------------------------------------------------+

參考資料

  • 關于 Postgresql 的范圍數據類型, 參考 范圍類型

  • Postgresql 范圍操作符

總結

以上是生活随笔為你收集整理的Elixir Ecto: 范围数据类型的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。