Mongodb Mongo到Postgres迁移-将Mongo hexa Id字段转换为更短的整数
我正在将MongoDB迁移到postgres 多亏了postgres JSON,这使得将嵌套文档作为JSON移动变得很容易。但问题开始于迁移“ID”字段 Mongo生成一个大的十六进制数Mongodb Mongo到Postgres迁移-将Mongo hexa Id字段转换为更短的整数,mongodb,postgresql,int,migration,bigint,Mongodb,Postgresql,Int,Migration,Bigint,我正在将MongoDB迁移到postgres 多亏了postgres JSON,这使得将嵌套文档作为JSON移动变得很容易。但问题开始于迁移“ID”字段 Mongo生成一个大的十六进制数56c4100560b2d8308f4bde21 我尝试将其转换为BigInt,但不幸的是,它超出了范围26397231623443762880753094891 无法重新生成ID,因为它已在各地的文档之间链接 字符串不能用作ID字段,因为我正在移动到Postgres+JPA,我将使用自动生成序列向前移动 有没有
56c4100560b2d8308f4bde21
我尝试将其转换为BigInt,但不幸的是,它超出了范围26397231623443762880753094891
我尝试使用模数,但它带来了重复您最好的选择是将MongoDB的
ObjectId
字段迁移到PostgreSQL的列中。请注意,UUID中有更多字节,因此需要填充这些值
更多信息请参见:
bigint
s,有两个选项:
1。创建全新的价值观
- 在此模式中,使用
/text
作为varchar
值(目前)ObjectId
为所有ObjectId
列创建
ObjectId
列的表创建ObjectId
列(当它们仍然是text
/varchar
):
(这将把更改传播到引用表,因为外键是在前面设置的。)ObjectId
列的列类型更改为bigint
所有
nextval('table\u name\u object\u id\u col\u seq')
作为默认值XOR
(通常是PostgreSQL中的#
运算符)而不是模数
使用此函数f.ex。您可以将原始值用作:
0
开始(或使用其他固定起始值)#
create or replace function hex_xor(p_hex text, p_bits int default 64, p_default bigint default 0)
returns bigint
language sql
immutable
as $func$
with recursive r as (
select ('x' || p_hex)::varbit h, p_default r, 0 i
union all
select case
when bit_length(h) <= p_bits then varbit ''
else substring(h for bit_length(h) - p_bits)
end,
r # case
when bit_length(h) <= p_bits then h::bit(64)::bigint
else substring(h from bit_length(h) - p_bits + 1 for p_bits)::bigint
end,
i + 1
from r
where bit_length(h) > 0
)
select r
from r
order by i desc
limit 1
$func$;
移民时。这样,迁移的ObjectId
s将始终为负值&随后生成的主键(例如,从序列中生成的主键)将始终为正值
您可以使用与bytea相同的十六进制,我想应该是int/bigint。不幸的是,我无法更改它,此时您可能需要一些映射。像创建一个bigint序列用作ID和迁移数据save map old_hex->new_int somewhere通常,当您想将原始值用作
bigint
f.ex时,这些字段被迁移为a(这在JPA实现中通常得到很好的支持:例如,您可以通过多种方式生成随机UUID)。(并希望使用自动递增值)存在一个问题:如果现有行中出现一个较小的值,则解决方案将在到达该值时开始拒绝某些INSERT
。请参阅f.ex。和
create or replace function hex_xor(p_hex text, p_bits int default 64, p_default bigint default 0)
returns bigint
language sql
immutable
as $func$
with recursive r as (
select ('x' || p_hex)::varbit h, p_default r, 0 i
union all
select case
when bit_length(h) <= p_bits then varbit ''
else substring(h for bit_length(h) - p_bits)
end,
r # case
when bit_length(h) <= p_bits then h::bit(64)::bigint
else substring(h from bit_length(h) - p_bits + 1 for p_bits)::bigint
end,
i + 1
from r
where bit_length(h) > 0
)
select r
from r
order by i desc
limit 1
$func$;
select -hex_xor('56c4100560b2d8308f4bde21', 63)