Postgres 查询使用 knex 删除多个连接数组中的重复项
Postgres query to remove duplicates in multiple joined arrays using knex
我正在使用 knex 构建一个 postgres 查询,并且有 table 个食谱与 table 个成分和步骤(每个步骤都是一条指令)。我试图在查询中将步骤和成分聚合到它们自己的数组中。我的问题是,一旦我加入第二个数组,两个数组都失去了它们的独特性(即 table a 有 2 个元素,table b 有 3 个元素;在我加入 table b 之后;两者数组现在有 6 个元素)。
我试过使用 distinct,但每次尝试都会引发错误。
这是我要输出的内容:
"id": 1,
"title": "sometitle",
"ingredients": [
{
"ingredient": "avacado",
"quantity": 24
},
{
"ingredient": "asparagus",
"quantity": 42
},
],
"instructions": [
{
"step": 1,
"instruction": "one"
},
{
"step": 2,
"instruction": "two"
},
{
"step": 3,
"instruction": "three"
},
]
这是我目前的情况:
knex(`recipes as r`)
.where({'r.id': 1})
.join('ingredients_list as list', {'list.recipe_id': 'r.id'})
.join('ingredients', {'list.ingredient_id': 'ingredients.id'})
.join('instructions', {'instructions.recipe_id': 'r.id'})
.select(
'r.id',
db.raw(`json_agg(json_build_object(
'ingredient', ingredients.name,
'quantity', list.quantity
)) as ingredients`),
db.raw(`json_agg(json_build_object(
'step', instructions.step_number,
'instruction', instructions.description
)) as instructions`)
)
.groupBy('r.id')
.first()
这是我想出的解决方案,以防其他人遇到此问题。我认为这是可行的,因为 postgres 无法评估 json 对象的相等性;而 jsonb 是一个二进制对象。我希望有人对此有更详尽的解释。
distinct json_agg(jsonb_build_object(...))
knex(`recipes as r`)
.where({'r.id': 1})
.join('ingredients_list as list', {'list.recipe_id': 'r.id'})
.join('ingredients', {'list.ingredient_id': 'ingredients.id'})
.join('instructions', {'instructions.recipe_id': 'r.id'})
.select(
'r.id',
db.raw(`distinct json_agg(jsonb_build_object(
'ingredient', ingredients.name,
'quantity', list.quantity
)) as ingredients`),
db.raw(`distinct json_agg(jsonb_build_object(
'step', instructions.step_number,
'instruction', instructions.description
)) as instructions`)
)
.groupBy('r.id')
.first()
我正在使用 knex 构建一个 postgres 查询,并且有 table 个食谱与 table 个成分和步骤(每个步骤都是一条指令)。我试图在查询中将步骤和成分聚合到它们自己的数组中。我的问题是,一旦我加入第二个数组,两个数组都失去了它们的独特性(即 table a 有 2 个元素,table b 有 3 个元素;在我加入 table b 之后;两者数组现在有 6 个元素)。
我试过使用 distinct,但每次尝试都会引发错误。
这是我要输出的内容:
"id": 1,
"title": "sometitle",
"ingredients": [
{
"ingredient": "avacado",
"quantity": 24
},
{
"ingredient": "asparagus",
"quantity": 42
},
],
"instructions": [
{
"step": 1,
"instruction": "one"
},
{
"step": 2,
"instruction": "two"
},
{
"step": 3,
"instruction": "three"
},
]
这是我目前的情况:
knex(`recipes as r`)
.where({'r.id': 1})
.join('ingredients_list as list', {'list.recipe_id': 'r.id'})
.join('ingredients', {'list.ingredient_id': 'ingredients.id'})
.join('instructions', {'instructions.recipe_id': 'r.id'})
.select(
'r.id',
db.raw(`json_agg(json_build_object(
'ingredient', ingredients.name,
'quantity', list.quantity
)) as ingredients`),
db.raw(`json_agg(json_build_object(
'step', instructions.step_number,
'instruction', instructions.description
)) as instructions`)
)
.groupBy('r.id')
.first()
这是我想出的解决方案,以防其他人遇到此问题。我认为这是可行的,因为 postgres 无法评估 json 对象的相等性;而 jsonb 是一个二进制对象。我希望有人对此有更详尽的解释。
distinct json_agg(jsonb_build_object(...))
knex(`recipes as r`)
.where({'r.id': 1})
.join('ingredients_list as list', {'list.recipe_id': 'r.id'})
.join('ingredients', {'list.ingredient_id': 'ingredients.id'})
.join('instructions', {'instructions.recipe_id': 'r.id'})
.select(
'r.id',
db.raw(`distinct json_agg(jsonb_build_object(
'ingredient', ingredients.name,
'quantity', list.quantity
)) as ingredients`),
db.raw(`distinct json_agg(jsonb_build_object(
'step', instructions.step_number,
'instruction', instructions.description
)) as instructions`)
)
.groupBy('r.id')
.first()