在 GraphQL 中处理 Mongoose 填充字段
Handling Mongoose Populated Fields in GraphQL
如何表示可以是简单 ObjectId
字符串或填充对象实体的字段?
我有一个代表 'Device type' 的猫鼬模式,如下所示
// assetSchema.js
import * as mongoose from 'mongoose'
const Schema = mongoose.Schema;
var Asset = new Schema({ name : String,
linked_device: { type: Schema.Types.ObjectId,
ref: 'Asset'})
export AssetSchema = mongoose.model('Asset', Asset);
我试图将其建模为 GraphQLObjectType,但我对如何允许 linked_ue
字段采用两种类型的值感到困惑,一种是 ObjectId
,另一种是完整的Asset
对象(填充时)
// graphql-asset-type.js
import { GraphQLObjectType, GraphQLString } from 'graphql'
export var GQAssetType = new GraphQLObjectType({
name: 'Asset',
fields: () => ({
name: GraphQLString,
linked_device: ____________ // stumped by this
});
我查看了联合类型,但问题是联合类型期望将字段规定为其定义的一部分,而在上述情况下,linked_device
字段下没有字段当 linked_device
对应于一个简单的 ObjectId
.
有什么想法吗?
事实上,您可以在 linked_device
字段中使用 union or interface 类型。
使用联合类型,可以实现GQAssetType
如下:
// graphql-asset-type.js
import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql'
var LinkedDeviceType = new GraphQLUnionType({
name: 'Linked Device',
types: [ ObjectIdType, GQAssetType ],
resolveType(value) {
if (value instanceof ObjectId) {
return ObjectIdType;
}
if (value instanceof Asset) {
return GQAssetType;
}
}
});
export var GQAssetType = new GraphQLObjectType({
name: 'Asset',
fields: () => ({
name: { type: GraphQLString },
linked_device: { type: LinkedDeviceType },
})
});
当我看到这篇文章时,我正试图解决拉取关系数据的一般问题。需要明确的是,最初的问题似乎是当字段可能包含 ObjectId 或 Object 时如何动态解析数据,但是我认为首先让字段存储对象或 objectId 并不是一个好的设计。因此,我有兴趣解决我将字段分开的简化场景——一个用于 Id,另一个用于对象。我还认为使用 Union 过于复杂,除非您实际上有另一种情况,如上面引用的文档中描述的那样。我认为下面的解决方案可能也会引起其他人的兴趣...
注意:我使用的是 graphql-tools,所以我的类型是书面模式语言语法。因此,如果您的用户类型具有如下字段:
type User {
_id: ID
firstName: String
lastName: String
companyId: ID
company: Company
}
然后在我的用户解析函数代码中,我添加:
User: { // <-- this refers to the User Type in Graphql
company(u) { // <-- this refers to the company field
return User.findOne({ _id: u.companyId }); // <-- mongoose User type
},
}
以上内容与现有的用户解析器功能一起使用,并允许您像这样编写 GQL 查询:
query getUserById($_id:ID!)
{ getUserById(_id:$_id) {
_id
firstName
lastName
company {
name
}
companyId
}}
此致,
小号。阿罗拉
如何表示可以是简单 ObjectId
字符串或填充对象实体的字段?
我有一个代表 'Device type' 的猫鼬模式,如下所示
// assetSchema.js
import * as mongoose from 'mongoose'
const Schema = mongoose.Schema;
var Asset = new Schema({ name : String,
linked_device: { type: Schema.Types.ObjectId,
ref: 'Asset'})
export AssetSchema = mongoose.model('Asset', Asset);
我试图将其建模为 GraphQLObjectType,但我对如何允许 linked_ue
字段采用两种类型的值感到困惑,一种是 ObjectId
,另一种是完整的Asset
对象(填充时)
// graphql-asset-type.js
import { GraphQLObjectType, GraphQLString } from 'graphql'
export var GQAssetType = new GraphQLObjectType({
name: 'Asset',
fields: () => ({
name: GraphQLString,
linked_device: ____________ // stumped by this
});
我查看了联合类型,但问题是联合类型期望将字段规定为其定义的一部分,而在上述情况下,linked_device
字段下没有字段当 linked_device
对应于一个简单的 ObjectId
.
有什么想法吗?
事实上,您可以在 linked_device
字段中使用 union or interface 类型。
使用联合类型,可以实现GQAssetType
如下:
// graphql-asset-type.js
import { GraphQLObjectType, GraphQLString, GraphQLUnionType } from 'graphql'
var LinkedDeviceType = new GraphQLUnionType({
name: 'Linked Device',
types: [ ObjectIdType, GQAssetType ],
resolveType(value) {
if (value instanceof ObjectId) {
return ObjectIdType;
}
if (value instanceof Asset) {
return GQAssetType;
}
}
});
export var GQAssetType = new GraphQLObjectType({
name: 'Asset',
fields: () => ({
name: { type: GraphQLString },
linked_device: { type: LinkedDeviceType },
})
});
当我看到这篇文章时,我正试图解决拉取关系数据的一般问题。需要明确的是,最初的问题似乎是当字段可能包含 ObjectId 或 Object 时如何动态解析数据,但是我认为首先让字段存储对象或 objectId 并不是一个好的设计。因此,我有兴趣解决我将字段分开的简化场景——一个用于 Id,另一个用于对象。我还认为使用 Union 过于复杂,除非您实际上有另一种情况,如上面引用的文档中描述的那样。我认为下面的解决方案可能也会引起其他人的兴趣...
注意:我使用的是 graphql-tools,所以我的类型是书面模式语言语法。因此,如果您的用户类型具有如下字段:
type User {
_id: ID
firstName: String
lastName: String
companyId: ID
company: Company
}
然后在我的用户解析函数代码中,我添加:
User: { // <-- this refers to the User Type in Graphql
company(u) { // <-- this refers to the company field
return User.findOne({ _id: u.companyId }); // <-- mongoose User type
},
}
以上内容与现有的用户解析器功能一起使用,并允许您像这样编写 GQL 查询:
query getUserById($_id:ID!)
{ getUserById(_id:$_id) {
_id
firstName
lastName
company {
name
}
companyId
}}
此致,
小号。阿罗拉