[英]Postgres query to remove duplicates in multiple joined arrays using knex
I'm using knex to build a postgres query and have a table of recipes with a many to many relationship to both a table of ingredients and steps (each step being a part of an instruction).我正在使用 knex 来构建 postgres 查询,并有一个食谱表,其中包含与成分表和步骤表(每个步骤都是指令的一部分)的多对多关系。 I'm trying to aggregate both the steps and ingredients into their own arrays within the query.
我试图在查询中将步骤和成分聚合到它们自己的数组中。 My problem is as soon as I join the second array both arrays lose their distinctiveness (ie. table a has 2 elements, table b has 3 elements; after I join table b; both arrays now have 6 elements).
我的问题是,一旦我加入第二个数组,两个数组就会失去它们的独特性(即表 a 有 2 个元素,表 b 有 3 个元素;加入表 b 后;两个数组现在都有 6 个元素)。
I've tried using distinct but every attempt has resulted in an error being thrown.我试过使用 distinct 但每次尝试都导致抛出错误。
Here's what I'm trying to output:这是我试图输出的内容:
"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"
},
]
Here's what I have so far:这是我到目前为止所拥有的:
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()
Here's the solution I came up with in case anyone else runs into this issue.这是我想出的解决方案,以防其他人遇到此问题。 I assume this works because postgres is unable to evaluate equality of json objects;
我认为这是有效的,因为 postgres 无法评估 json 对象的相等性; whereas jsonb is a binary object.
而 jsonb 是一个二进制对象。 I'd love a more thorough explanation of this is somebody has one.
我希望对此有更彻底的解释,因为有人有这种解释。
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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.