下面是原始查询的示例。
const query = `SELECT
links.name, links.type, links.code, links.originalUrl,
domains.id as 'domain.id', domains.host as 'domain.host',
count(
CASE WHEN hits.datetime > "${past}" AND hits.datetime <= "${now}" = true then 1 END
) as hitCount
FROM links
LEFT JOIN hits ON links.id = hits.linkId
LEFT JOIN domains ON links.domainId = domains.id
WHERE links.userId = ${req.user.id}
GROUP BY links.id, hits.linkId
ORDER BY hitCount DESC
LIMIT 5`;
const links = await sequelize.query(query.trim(), {
type: sequelize.QueryTypes.SELECT,
model: Link,
mapToModel: true
});
我正在使用Link
将查询结果映射到模型mapToModel: true
中。效果很好,但是当我尝试从连接的表中获取一些数据并将其映射到模型中的对象时,它不会转换为数组。
例如,我正在尝试获取domains.id as 'domain.id', domains.host as 'domain.host',
之类的域,这就是我看到对查询急切加载的数据进行序列化的方式。
但是当我得到结果对象时,却没有嵌套的域对象属性。
// desired link object
{
id: 3,
name: 'My test link',
domain: {
id: 23,
host: 'example.com'
}
}
相反,我得到的是
// current link object
{
id: 3,
name: 'My test link',
'domain.id': 23,
'domain.host': 'example.com'
}
因此嵌套对象无法正确映射。
我找到了nest
options in query()
文档,但设置nest: true
似乎没有任何效果。
更改的查询
const links = await sequelize.query(query.trim(), {
type: sequelize.QueryTypes.SELECT,
model: Link,
mapToModel: true,
nest: true, // doesn't have any effect
});
答案 0 :(得分:2)
我遇到了同样的问题。我的解决方案是:
return sequelize.query(/* query */, {
nest: true,
type: sequelize.QueryTypes.SELECT
});
如您所见,您不应设置 mapToModel 道具,而应设置嵌套和 type 。
答案 1 :(得分:2)
对我来说nest
仅与raw
一起工作:
const links = await sequelize.query(query.trim(), {
type: sequelize.QueryTypes.SELECT,
model: Link,
mapToModel: true,
nest: true,
raw: true // Without this `nest` hasn't effect, IDK why
});
答案 2 :(得分:0)
据我所知,Link模型具有一个关联的域,因此您需要通过
include: <domain model>
映射到域模型。
答案 3 :(得分:0)
您可以自己安装dottie
,这就是nest: true
应该做的(https://github.com/mickhansen/dottie.js):
import dottie from 'dottie';
// ...
const formattedLinks = links.map(l => dottie.transform(l.toJSON()))
答案 4 :(得分:0)
使用 nest:true
的原始查询似乎不适用于 mapToModel
。所以我发现的唯一方法是包含 nest:true
,使用 Link.build(link)
和 { include: Domain}
选项映射:
const query = `SELECT
links.name, links.type, links.code, links.originalUrl,
domains.id as 'domain.id', domains.host as 'domain.host',
count(
CASE WHEN hits.datetime > "${past}" AND hits.datetime <= "${now}" = true then 1 END
) as hitCount
FROM links
LEFT JOIN hits ON links.id = hits.linkId
LEFT JOIN domains ON links.domainId = domains.id
WHERE links.userId = ${req.user.id}
GROUP BY links.id, hits.linkId
ORDER BY hitCount DESC
LIMIT 5`;
const links = (await sequelize.query(query.trim(), {
nest: true,
type: sequelize.QueryTypes.SELECT,
}));
links.map((link) => Link.build(link, {include: Domain}))