我在strapi的postgresql中有两个表:商品和标签
Goods:
id | title
---------
1 | some name
2 | some name 2
3 | some name 4
…………………
Labels
id | title
------------
1 | some label 1
2 | some label 2
3 | some label n
………………………
它们通过附加表彼此多对多连接
goods_labels__labels_goods
id | good_id | label_id
----------------------------
1 | 1 | 1
2 | 1 | 2
2 | 2 | 1
我需要选择与 label.id = 1 和 label.id = 2 都有关系的商品,这只是第一个 id = 1 的商品。有什么方法可以使用带有 graphql 或 bookshelf 的标准 Strapi 工具来实现它,或者作为最后的手段通过原始查询? 我还需要对这个请求进行排序和限制
好的。内容就在这里
我在 Strapi 中有两种内容类型,例如标签和文章。并且想要过滤具有多个标签(例如1、2、4)的文章。在标准的 Strapi 中,你不能这样做。所以我必须更改 Strapi 文章 api 的默认行为。您可以在这里
找到该文档我们需要定义特殊参数来实现我们的目标。事实上我在查询参数中选择了 multiTag
query{
multiTag: [1,2,3]
}
在您的项目中打开文件
/src/api/article/controllers/article.js
!注意:路径会随着您的内容类型名称而变化。
你应该得到这个
const { createCoreController } = require('@strapi/strapi').factories;
module.exports = createCoreController('api::article.article');
然后添加一些代码
async function getMultiTag(conn, multiTag){
// the sql should like this
const sql = `
select
t.id
from
article t
inner join (
select article_id from article_link_tag
where tag_id in (${string(multiTag})
group by article_id having count(*) = ${multiTag.length}
)t2 on t.id = t2.article_id
`
const result = await conn.raw(sql)
// result should like this
[
// actual data
[
{"id" : 1}
],
// meta info
[
{
"db" : 1
}
]
]
return result[0]
}
module.exports = createCoreController('api::pet-article.pet-article', ({ strapi }) => ({
async find(ctx) {
ctx.query = { ...ctx.query, local: 'en' }
// get the param
const multiTag = ctx.query?.multiTag
if (multiTag && typeof multiTag == 'object' && multiTag.length > 0) {
// get the database connection
const conn = strapi.db.connection
const articles = await getMultiTag(conn, multiTag)
// when you have got the ids of article
// you can do many things
// like this
ctx.query.filter = {
...(ctx.query.filter || {}),
id: {
$in: articles.map(val => val.id)
}
}
// or just return the ids
// return { data: articles }
}
const { data, meta } = await super.find(ctx);
meta.date = Date.now()
return { data, meta };
},
}));
我还没有测试过它,但根据文档,尝试这个:
const hasAnyLabel = {
labels: {
id: {
$in: [1,2]
}
}
};
const hasAllLabels = {
labels: {
$and: [
{id: 1},
{id: 2},
]
}
};
const goods = await strapi.db.query('api::goods.goods').findMany({
where: hasAllLabels,
populate: ['labels']
});