FeathersJS和MongoDB的不同结果是从HTTP GET和service.find中查询字段

时间:2017-11-14 21:07:22

标签: mongodb feathersjs

从特定字段查询服务时,我得到的响应不同,具体取决于我是在服务器上使用CURL还是运行app.service()。find()。我正在使用MongoDB,这是我的结果示例。

// Here's a list of all data in the service
curl 'http://192.168.99.100:3030/players/'
[
    {"_id":"5a04bd4eee3648000fbad08f","userId":"59f8e18c14b066000ff63cbb","gameId":"5a04bd4eee3648000fbad08e","isHost":true,"handle":"dude"},
    {"_id":"5a0b41bbacd285000ffb310c","userId":"59f8e18c14b066000ff63cbb","gameId":"5a0b41bbacd285000ffb310b","isHost":true,"handle":"dude"},
    {"_id":"5a0b440aacd285000ffb310d","gameId":"5a0b41bbacd285000ffb310b"},
    {"_id":"5a0b44f7acd285000ffb310e","gameId":"5a0b41bbacd285000ffb310b"},
    {"_id":"5a0b498dc31cea000fef17dd","gameId":"5a0b41bbacd285000ffb310b","userId":"5a0b4117acd285000ffb310a","handle":"dog"},
    {"_id":"5a0b4a76c31cea000fef17de","gameId":"5a0b41bbacd285000ffb310b","userId":"5a0b4117acd285000ffb310a","handle":"dog"}
]}

// If I query on the gameId 5a0b41bbacd285000ffb310b from curl, it only returns 
// 4 of 5 rows skipping the first player
curl 'http://192.168.99.100:3030/players/?gameId=5a0b41bbacd285000ffb310b' 
[
    {"_id":"5a0b440aacd285000ffb310d","gameId":"5a0b41bbacd285000ffb310b"},
    {"_id":"5a0b44f7acd285000ffb310e","gameId":"5a0b41bbacd285000ffb310b"},
    {"_id":"5a0b498dc31cea000fef17dd","gameId":"5a0b41bbacd285000ffb310b","userId":"5a0b4117acd285000ffb310a","handle":"dog"},
    {"_id":"5a0b4a76c31cea000fef17de","gameId":"5a0b41bbacd285000ffb310b","userId":"5a0b4117acd285000ffb310a","handle":"dog"}
]}


// When I run this query server side passing gameID = 5a0b41bbacd285000ffb310b
// I only get the first created player in the list.
var gameID = hook.result._id;
app.service('players').find({
    query:{
      gameId: gameID,
    }
}).then(players => {
    console.log(players);
});
[
    {"_id":"5a0b41bbacd285000ffb310c","userId":"59f8e18c14b066000ff63cbb","gameId":"5a0b41bbacd285000ffb310b","isHost":true,"handle":"dude"}
]

我的过滤器是空白的,并且钩子不会删除数据,只是从userId获取“句柄”。

似乎查询可能不起作用,因为数据类型可能存在差异。如在fieldname gameId或存储的数据中。

在使用钩子创建游戏对象后,玩家5a0b41bbacd285000ffb310c中的第一个ID从服务器端获得了gameId。像这样:

// This hook is run after a new game is created
return function joinNewGame (hook) {
    var userid = hook.params.user._id;
    var gameid = hook.result._id;

    return hook.app.service('players').create({
            userId: userid,
            gameId: gameid,
            isHost: true,
        }).then(player => {

            return hook;
        });
};

其他玩家是在一个帖子请求中写的,其中gameId作为字符串传递。

curl 'http://192.168.99.100:3030/players/' -H 'Content-Type: application/json' --data-binary '{ "gameId":"5a0b41bbacd285000ffb310b"}'

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

经过一些额外的测试后,我发现这是打字错误。服务器端创建的条目的gameId类型是“对象”,而客户端是“字符串”。

所以我目前的修复方法是在从服务器存储/查询之前将id转换为字符串。这是在ORM中建立多对一关系的最佳方式吗? Docs没有详细说明。

更新:这是一个不同的修复,我创建了一个新的钩子,在存储数据时将字符串转换为MongoDB对象ID,传递需要在数组中更新的字段。

var ObjectID = require('mongodb').ObjectID;

module.exports = function (fields, options = {}) { // eslint-disable-line no-unused-vars
  return function stringToObjectId (hook) {
    // For each passed field
    for(var i = 0; fields.length > i; i++){
      // Test if there's queries on the field, then convert
      if(hook.params.query && typeof hook.params.query[fields[i]] != "Object"){
        hook.params.query[fields[i]] = ObjectID(hook.params.query[fields[i]]);
      }
      // Test if there's data on the field, then convert
      if(hook.data && typeof hook.data[fields[i]] != "Object"){
        hook.data[fields[i]] = ObjectID(hook.data[fields[i]]);
      }
    }
    return Promise.resolve(hook);
  };
};