【问题标题】:How to return an aggregate query in an Apollo resolver (Meteor/Apollo/Graphql)?如何在 Apollo 解析器(Meteor/Apollo/Graphql)中返回聚合查询?
【发布时间】:2023-03-13 18:20:02
【问题描述】:

我正在尝试在 Meteor 中使用聚合运行查询,但我无法弄清楚如何返回聚合查询。

在我的 GraphQL 架构中:

type UserRelation {
    date: String!
    userID: String!
}
type UserData {
    userID: String!
    description: String!
    friends_list: [UserRelation]!
}
extend type Query {
    getFriends(userID: String!, friendID: String): [UserRelation]
}

在我的 resolvers.js 中:

import UserData from "./userData";
export default {
    Query: {
        getFriends(obj, args, context) {
            if (args.friendID) return UserData.rawCollection().aggregate([
                {
                    $match: {
                        _id: 'cuS7KebEQDRv2iFpJ'    
                    }
                },
                {
                    $unwind: '$friends_list'
                },
                {
                    $match: {
                        'friends_list._id': '8GW4gjwWhkEexfndd'
                    }
                }
            ]);
            return UserData.findOne({ userID: args.userID }, {fields: {_id: 0,  friends_list: 1 }}).friends_list;
        }
    }
}

在这个硬编码示例中,我的数据库中有以下文档:

我想返回整个文档,只包含具有匹配_id 的用户,并且其friends_list 有另一个具有第二个匹配_id 的用户。所以这样我就可以返回整个文档,只包含 friends_list 数组中的 1 个元素,而不是所有其他元素。

现在这个查询在 Robo3T(一个 MongoDB GUI)中运行良好,但是当我在 Graphiql 中运行它时,返回语句存在问题,因为抛出了一个错误,其中指出: "Expected Iterable, but did not find one for field \"Query.getFriends\"." 当我记录该语句时,我看到了 Mongo AggregationCursor。但我不确定我应该如何将其“转换”为解析器可以正确返回的类型。

感谢您的帮助,谢谢!

【问题讨论】:

  • findOne 不返回数组?
  • 不,这不适用于 findOne,这部分工作正常。 findOne 返回特定用户的整个friends_list 数组。 findOne 仅在未指定可选的friendID 参数时运行,在这种情况下我返回整个friends_list 数组。
  • 只在返回前记录数据,检查结构,与预期比较
  • 我这样做了,它显示了一个 AggregationCursor。我不确定如何将其“转换”为适当的东西,但我认为根据下面的回答,我可能(?)已经弄清楚了。

标签: mongodb meteor graphql mongodb-query apollo


【解决方案1】:

我不知道我是否真的想通了,因为我需要对其进行更多测试,但到目前为止,这是可行的,在我的 resolvers.js 中我有:

import UserData from "./userData";
async function getFriend(userID, friendID) {
    return UserData.rawCollection().aggregate([
        {
            $match: {
                _id: userID    
            }
        },
        {
            $unwind: '$friends_list'
        },
        {
            $match: {
                'friends_list._id': friendID
            }
        }
    ]).toArray();
}

export default {
    Query: {
        async getFriends(obj, args, context) {
            if (args.friendID){
                const result = await getFriend(args.userID, args.friendID);
                return result[0].friends_list;
            }
            return UserData.findOne({ userID: args.userID }, {fields: {_id: 0,  friends_list: 1 }}).friends_list;
        }
    }
}

通过使其异步,我能够完成这项工作。不知道这有什么影响,但到目前为止它有效。如果有人能够对此进行审查并提出一些批评以改进它,我们将不胜感激,因为有关此的任何信息都很难找到,因为到目前为止我还没有看到任何用例。

【讨论】:

    猜你喜欢
    • 2017-12-09
    • 2020-09-12
    • 2020-06-06
    • 2019-04-06
    • 1970-01-01
    • 2020-06-27
    • 2021-10-17
    • 2020-11-02
    • 2021-01-25
    相关资源
    最近更新 更多