2014-05-02 141 views
0

我正在Meteor JS上构建一个游戏引擎,并试图创建一种链接多个集合的方法。目前的'模式'看起来像这样:Mongodb中的关系映射

GameCollection = { <meta> } //This is a Collection (a Meteor MongoDB document) 

Scene = {gameId: _id, <other resource ids and meta>} //This is a Collection 

问题是我需要创建一个地图从一个场景到另一个场景。这些路径需要轻松分叉和合并。我感觉我应该使用图形/三重数据库来表示这一点,但我想在“流星的魔力”中说,这意味着正常的MongoDB集合。如果有人有一个简单易用的替代方案,我仍然希望听到它,但我更喜欢Meteor-esk模式。推向正确的方向也将是伟大的!

我有三个特殊需求:

  1. 如果我在这个现场是什么场景或场景做我导致。
  2. 如果我在这个场景,那么给我所有场景的id和未来的步数。其中'x'是一个变量(所以我可以将它们的大部分发送给客户端)
  3. 计数并给我所有可能的路径,以便我可以给出游戏的视觉表示。

我正在寻找的是:是一个图数据库,我正在寻找,如果不是我应该用什么模式模式与mongoDB?

UPDATE:

我已确认的Neo4j会做什么,我从逻辑的观点来看需要。但是我会失去使用Meteor Collections的好处。这意味着失去反应能力,从而打破我的现场协作模式。我真的需要一个MongoDB的选择。

更新2:

最后我想粘GameCollection内部的关系。它似乎在工作,但如果可能的话,我想要一个更清洁的方式。

map: [ { //an array of objects (relations) 
    id: _id //key to a Scene 
    toKey: _id //leads to scene; toKey is ether 'next' or some num [0..n] for multi paths 
}] 

回答

0

所以我结束了去非规范化的路线。我将一系列场景放入GameCollection中。

scenes: [{ id: random_id, next: 'next_id' || [next_ids], <other resource ids and meta> }] 

然后我建这个怪物:

getScene = function (scenes, id) { 
return _.find(scenes, function (scene) { 
    return (scene.id == id) 
}) 
} 

getNext = function (scene) { 
if (!scene) { return null } 
if (scene.type == 'dialogue') { 
    return scene.next 
} 
if (scene.type == 'choice') { 
    return _.pluck(scene.next, 'id') 
} 
} 

scenesDive = function (list, next, container, limit, depth) { 
if (!depth) { 
    depth = 0 
} 
myDepth = depth + 1 
var scene = getScene(list, next) 
if (container.indexOf(scene) != -1) { return } //This path has already been added. Go back up. 
container.push(scene) 
if (myDepth == limit) { return } //Don't dive deeper then this depth. 

var nextAoS = getNext(scene) //DIVE! (array or string) 
if (_.isArray(nextAoS)) { 
    nextAoS.forEach(function (n) { 
    scenesDive(list, n, container, limit, myDepth) 
    }); 
} else { 
    scenesDive(list, nextAoS, container, limit, myDepth) 
} 
} 

我肯定有一个更好的办法,但是这是我与现在去。