使用干净的语法查询Google Datastore中的多个实体

时间:2016-10-23 01:22:47

标签: google-app-engine google-cloud-datastore

我将node.js与Google App Engine一起用于课程项目。我的代码工作正常,所以我不会问如何解决这个问题,但这超出了理由,我认为必须有一个更好的方法来使这看起来干净。这不是我成绩的一部分,只是想知道更好的方法。此外,总是希望减少往返次数,所以

我已经构建了一个基本的论坛后端,但创建论坛帖子的一部分是我需要检查该线程是否具有唯一的名称并且该用户是否存在。计划稍后添加身份验证,但现在只需查询名称。

有没有办法使用单个查询按键获取2个实体,如果它们属于不同的种类'?像这样的嵌套查询似乎很糟糕。没有找到关于这个主题的大量文档,或者我的google-fu有点弱。在几个地方做这样的事情,所以特别希望改善这一点。

基本代码

router.post('/', function (req, res) {

    if (req.body["Name"] == null || typeof req.body["Name"] !== "string")
    {
        res.json({ success: false, data: "Name was not a valid string." });
        return;
    }

    if (req.body["Creator"] == null || typeof req.body["Creator"] !== "string")
    {
        res.json({ success: false, data: "Invalid creator submitted for thread creation." });
        return;
    }

    //See if thread is unique
    var query = datastore.createQuery('Thread')
        .filter('__key__', '=', datastore.key(['Thread', req.body["Name"]]));

    datastore.runQuery(query, function (err, entities, nextQuery) {

        //
        if (err == null && entities.length == 0) {

            var query2 = datastore.createQuery('User')
                .filter('__key__', '=', datastore.key(['User', req.body["Creator"]]));

            datastore.runQuery(query2, function (err2, entities2, nextQuery) {

                if (err2 == null && entities2.length >= 1)
                {
                    var threadKey =
                        {
                            name: req.body["Name"],
                            kind: "Thread",
                            path: ["Thread", req.body["Name"]]
                        }

                    var threadData =
                        {
                            Creator: req.body["Creator"],
                            DateCreated: new Date(),
                            LastUpdated: new Date()
                        }

                    datastore.upsert({
                        key: threadKey,
                        data: threadData
                    }, function (err) {

                        if (err) {
                            res.json({ success: false, data: "Was unable to add value to datastore for unknown reason." });
                            return;
                        }
                        else {
                            res.json({ success: true, data: "Was able to add thread to datastore." });
                            return;
                        }
                    });
                }
                else
                {
                    res.json({ success: false, data: "Cannot create thread because a valid user was not submitted." });
                    return;
                }
            });
        }
        else {
            res.json({ success: false, data: "Cannot create thread because a matching name already exists." });
            return;
        }
    });
});

1 个答案:

答案 0 :(得分:1)

由于查询位于Kind,因此您无法跨Kind运行单个查询。但是,如果一个Kind是另一个的祖先,那么单个查询可以同时获得两者。例如,如果creatorThread的属性,而创建它的User,则线程上的查询也可以包含创建者的属性。

更多信息:https://cloud.google.com/datastore/docs/concepts/entities#ancestor_paths