Elixir Ecto:범위 데이터 유형
price_range
으로 min_price
을 대체할 수 있다. max_price
은 하나의 가격 범위를 나타낸다.Ecto에서 범위 데이터 유형 사용
가격 범위의 표시 방법은 다음과 같다.
[0, 45.67]
[30.04, 98.50]
[100, 500]
우리는 범위 조작부호로 한 값의 범위를 조회할 수 있다
2.5
Postgresql은 다음과 같은 범위 유형을 지원합니다.
104591710 정수 방위 104591810
104591710 104591410 - 큰 정수 범위 104591810
104591710 104591410 - 10진수 범위(부동) 104591810
104591710 104591410 - 시간대가 없는 타임 스탬프 범위 104591810
104591710 104591410 - 시간대 타임스탬프 범위 104591810
104591710 104591410 - 날짜 범위 104591810
Ecto 자체는 각 데이터베이스를 호환하기 위해 Postgresql 특유의 Range 데이터 형식을 지원하지 않지만, Ecto는 우리에게 사용자 정의 데이터 형식을 제공하는 방법을 제공했다.다음은
int4range
유형을 만들고 밑바닥은 Postgrex 어댑터의 int8range
구조를 사용했습니다.defmodule App.NumRange do
@behaviour Ecto.Type
def type, do: :numrange
def cast([lower, upper]) do
{:ok, [lower, upper]}
end
def cast(_), do: :error
def load(%Postgrex.Range{lower: lower, upper: nil}) do
{lower, _} = lower |> to_float
{:ok, [lower, nil]}
end
def load(%Postgrex.Range{lower: lower, upper: upper}) do
{lower, _} = lower |> to_float
{upper, _} = upper |> to_float
{:ok, [lower, upper]}
end
def dump([lower, upper]) do
{:ok, %Postgrex.Range{lower: lower, upper: upper, upper_inclusive: false}}
end
def dump(_), do: :error
defp to_float(value) do
value |> Decimal.to_string |> Float.parse
end
end
모델과 이전 스크립트에서 이 사용자 정의 데이터 형식을 사용합니다
모델
defmodule App.Product do
use App.Web, :model
schema "products" do
field :price_range, App.NumRange
timestamps
end
end
스크립트 마이그레이션
defmodule App.Repo.Migrations.Product do
use Ecto.Migration
def change do
create table(:products) do
add :price_range, :numrange
timestamps
end
end
end
범위 조회
defmodule App.ProductQuery do
import Ecto.Query
alias App.{Repo, Product}
def within_price_range(price) do
query =
from p in Product,
where: fragment("?::numeric Repo.all
end
end
방위 경계에 관한 문제는 수학의 범위 기호와 같다.
numrange
하단 경계 포함 tsrange
하단 경계 제외 tstzrange
상위 daterange
상위 예.
#
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'), '[]') |
+------+-------------------------------------------------------+
참고 자료
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Ecto의 "or_where"함정을 주의하십시오.이 게시물에서는 Ecto의 or_where 기능을 사용할 때 발생할 수 있는 오류를 강조하고 싶습니다. 단지 이 함수가 Ecto.Query 함수와 함께 작동하는 방식에 대해 잘못된 결론에 도달할 수 있는 방법일 뿐입...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.