【发布时间】:2017-04-02 21:25:37
【问题描述】:
我正在尝试找出一种简洁的方式来处理查询和 mongdb 投影,这样我就不必从数据库中检索过多的信息。 所以假设我有:
// the query
type Query {
getUserByEmail(email: String!): User
}
为了简单起见,我有一个 User 和一个 email 和一个 username。如果我发送查询并且只想检索电子邮件,我可以执行以下操作:
query { getUserByEmail(email: "test@test.com") { email } }
但是在解析器中,我的数据库查询仍然检索到username 和email,但只有其中一个被阿波罗服务器作为查询结果传回。
我只希望数据库检索查询要求的内容:
// the resolver
getUserByEmail(root, args, context, info) {
// check what fields the query requested
// create a projection to only request those fields
return db.collection('users').findOne({ email: args.email }, { /* projection */ });
}
当然问题是,获取有关客户请求的信息并不是那么简单。
假设我将请求作为上下文传递 - 我考虑使用具有查询字符串的 context.payload (hapi.js),并通过各种 .split()s 搜索它,但这感觉有点脏。据我所知,info.fieldASTs[0].selectionSet.selections 有字段列表,我可以检查它是否存在。我不确定这有多可靠。尤其是当我开始使用更复杂的查询时。
有没有更简单的方法?
如果您不使用 mongDB,投影是您传入的附加参数,明确告诉它要检索什么:
// telling mongoDB to not retrieve _id
db.collection('users').findOne({ email: 'test@test.com' }, { _id: 0 })
一如既往,感谢这个了不起的社区。p>
【问题讨论】:
-
好的。所以现在还不清楚你在问什么。该查询说“请返回
email”。 “但是在解析器中,我的数据库查询仍然检索两者,但只传回一个。我只希望数据库检索查询要求的内容”是什么意思?您应该共享此查询的解析器代码。 -
这也是我的错。我应该更清楚一点。我试图找出查询要查找的字段,以便我可以使我的数据库查询仅请求查询请求的信息。我将编辑我的问题以更好地反映这一点。
-
很抱歉很密集。仍然不清楚“查询请求的字段”是什么意思。这些领域是什么?查询是如何请求他们的?您的问题实际上是“如何进行包含有关我要执行的投影的信息的查询”?阅读这个问题听起来您认为查询已经告诉解析器“要投影的字段”是什么。您说“获取有关客户要求的信息并不简单”。实际上是的。客户要求的一切都在查询中。如果您想请求更多,请将其放在查询中。
-
为了使用投影,我需要知道查询要求哪些字段:
getUserByEmail(email: "someemail") { field }。也可以进行相同的查询:getUserByEmail(email: "someemail") { field1 field2 field3 }。如果我运行第一个查询,我需要执行db.collection('test').findOne({ args }, { field: 1 }),但对于第二个查询我需要执行db.collection('test').findOne({ args }, { field1: 1, field2: 1, field3: 1 })。我的问题是如何从解析器中获取该字段列表。 -
我终于明白了这个问题:) 我认为你做不到。它可能依赖于实现,但使用
apollo-server,您已经定义了查询模式。你的getUserByEmail返回一个User:就是这样。似乎要求数据库提供比这更少的信息是过早的优化。为什么不直接获取用户并完成它。在客户端apollo-client将缓存结果,因此下次如果您只有电子邮件,它会将其提供给您。
标签: mongodb hapijs graphql apollo-server