1

我有 2 个表之间的多:多关系:notetag,并且希望能够通过它们的tagId. 因为很多:很多我有一个连接表note_tag

我的目标是在我可以查询的 Postgraphile 生成的 Graphql 模式上公开一个计算字段,以及note表的其他属性。

我在玩弄postgraphile-plugin-connection-filter。这个插件可以通过 authorId (这将是 1:many)之类的东西进行过滤,但我无法弄清楚如何通过 many:many 进行过滤。我的笔记表上有一个名为 的计算列tags,它是 JSON。有没有办法“查看”这个 json 并找出 id = 1 的位置?

这是我的计算列tags

    create or replace function note_tags(note note, tagid text)
        returns jsonb as $$
            select
                json_strip_nulls(
                    json_agg(
                        json_build_object(
                            'title', tag.title, 
                            'id', tag.id,
                        ) 
                    )
                )::jsonb 
            from note
            inner join note_tag on note_tag.tag_id = tagid and note_tag.note_id = note.id
            left join note_tag nt on note.id = nt.note_id 
            left join tag on nt.tag_id = tag.id
            where note.account_id = '1'
            group by note.id, note.title;
        $$ language sql stable;

正如我理解上面的函数,我返回 jsonb,基于给定的 tagid (给函数): inner join note_tag on note_tag.tag_id = tagidid那么为什么在计算列时没有过滤 json呢?

我正在尝试进行这样的查询:

query notesByTagId {
  notes {
    edges {
      node {
        title
        id
        tags(tagid: "1")
      }
    }
  }
}

但是现在当我执行这个查询时,我会在tags字段中返回字符串化的 JSON。但是,所有标签都包含在 json 中,无论注释是否实际上属于该标签。

例如,这个 id = 1 的笔记应该只有 id = 1 和 id = 2 的标签。现在它返回数据库中的每个标签

{
  "data": {
    "notes": {
      "edges": [
        {
          "node": {
            "id": "1",
            "tags": "[{\"id\":\"1\",\"title\":\"Psychology\"},{\"id\":\"2\",\"title\":\"Logic\"},{\"id\":\"3\",\"title\":\"Charisma\"}]",
            ...

这个计算列的关键因素是 JSON 必须包含笔记所属的所有标签,即使我们在单个上搜索笔记tagid

这是我的简化表...

笔记:

create table notes(
  id text, 
  title text
)

标签:

create table tag(
  id text,
  title text
)

注意标签:

create table note_tag(
  note_id text FK references note.id
  tag_id text FK references tag.id
)

更新

我正在稍微改变方法,并且正在玩弄以下功能:

    create or replace function note_tags(n note)
        returns setof tag as $$
            select tag.*
            from tag
            inner join note_tag on (note_tag.tag_id = tag.id)
            where note_tag.note_id = n.id;
        $$ language sql stable;

我能够检索tags填充字段的所有笔记,但现在我需要能够过滤掉不属于特定标签的笔记,同时仍然保留属于给定笔记的所有标签。

所以问题还是和上面一样:我们如何根据相关表的 PK 过滤表?

4

1 回答 1

1

经过一段时间的挖掘,我想我遇到了一个很好的方法。基于此响应,我创建了一个函数,该函数notes按给定返回所有内容tagid

这里是:

    create or replace function all_notes_with_tag_id(tagid text)
        returns setof note as $$
            select distinct note.*
            from tag
            inner join note_tag on (note_tag.tag_id = tag.id)
            inner join note on (note_tag.note_id = note.id)
            where tag.id = tagid;
        $$ language sql stable;

方法的错误是期望计算列完成所有工作,而它唯一的工作应该是获取所有数据。all_nuggets_with_bucket_id现在可以像这样在 graphql 中直接调用此函数:

query MyQuery($tagid: String!) {
  allNotesWithTagId(tagid: $tagid) {
    edges {
      node {
        id
        title
        tags {
          edges {
            node {
              id
              title
            }
          }
        }
      }
    }
  }
}
于 2020-09-07T20:18:14.983 回答