Javascript 如何基于变量动态设置嵌套文档的mongodb字段名?
我正在尝试将数据插入Mongodb文档中,用于一个使用Meteor编码的游戏,基于它的回合数 我希望最终结果是这样的:Javascript 如何基于变量动态设置嵌套文档的mongodb字段名?,javascript,mongodb,meteor,Javascript,Mongodb,Meteor,我正在尝试将数据插入Mongodb文档中,用于一个使用Meteor编码的游戏,基于它的回合数 我希望最终结果是这样的: { "room" : "TEST", "createdAt" : ISODate("2015-07-05T22:04:47.931Z"), "started" : true, "round" : 2, "players" : [ { "userId" : "ASDF", "playerName" : "Ed" }, {
{
"room" : "TEST",
"createdAt" : ISODate("2015-07-05T22:04:47.931Z"),
"started" : true,
"round" : 2,
"players" : [
{
"userId" : "ASDF",
"playerName" : "Ed"
},
{
"userId" : "ZXCV",
"playerName" : "Joe"
}
],
"answers" : {
"1": [
{
"userId" : "ASDF",
"answer" : "asdf"
},
{
"userId" : "ZXCV",
"answer" : "adfafa"
}],
"2": [
{
"userId" : "ASDF",
"answer" : "hello"
},
{
"userId" : "ZXCV",
"answer" : "hi"
}]
}
}
var q = {};
q[round] = round;
update: { $addToSet: q }
下面的javascript用于Meteor包,该包提供findAndModify功能。这就是语法与标准MongoDB略有不同的原因,但它基本上解析参数并向Mongo后端发送适当的查询,因此最终结果与标准相同。我想解决的部分是$addToSet参数
result = Rooms.findAndModify({
query: {
players: {
$elemMatch: {
userId: userId
}
}
},
update: {
$addToSet: {
answers: {
round: { // Where round is substituted with "1", "2" etc
userId: userId,
answer: answer
}
}
},
$inc: {
count: 1
}
},
new: true
});
我还发现了其他一些问题,人们基本上创建了一个占位符变量并向其中添加了值,结果是这样的:
{
"room" : "TEST",
"createdAt" : ISODate("2015-07-05T22:04:47.931Z"),
"started" : true,
"round" : 2,
"players" : [
{
"userId" : "ASDF",
"playerName" : "Ed"
},
{
"userId" : "ZXCV",
"playerName" : "Joe"
}
],
"answers" : {
"1": [
{
"userId" : "ASDF",
"answer" : "asdf"
},
{
"userId" : "ZXCV",
"answer" : "adfafa"
}],
"2": [
{
"userId" : "ASDF",
"answer" : "hello"
},
{
"userId" : "ZXCV",
"answer" : "hi"
}]
}
}
var q = {};
q[round] = round;
update: { $addToSet: q }
但是,这只适用于键值对。我想我需要得到如下东西:
update: {
$addToSet:
answers: {
round: { // Where round is dynamically substituted with "1", "2" etc
userId: userId,
answer: answer
}
}
}
如下所示:
update: {
$addToSet:
answers: {
"1": {
userId: userId,
answer: answer
}
}
}
我猜我必须用我想插入的嵌套块构建一个JSON对象,但我不知道如何做到这一点?嵌套结构真让我困惑
更新:
除了下面FuzzyBabunny的回答之外,我还阅读了另一篇文章中提到的这篇文章,并提出了同样的效果。这只是看待同一事物的另一种方式
var r = {}
var t = {}
t.userId = userId;
t.answer = answer;
r[round] = t;
$addToSet: r
以编程方式为
find和modify
创建整个参数:
// I'm assuming round, userId, and answer are defined somewhere already
// Create a function that returns an object with a custom keyname and value
var createObject = function(keyName, value){
// I have this typeof check because key names cannot be an integer
if(typeof keyName !== "string"){
console.log("ERROR! keyName needs to be a string.");
} else {
var obj = {};
obj[keyName] = value;
return obj;
}
};
var round = "3";
var userAndAnswer = {
userId: "SDFSD",
answer: "hello"
};
var findAndModifyArgument = {
query: {
players: {
$elemMatch: {
userId: userId
}
}
},
update: {
$addToSet: {
answers: createObject(round, userAndAnswer)
},
$inc: {
count: 1
}
},
new: true
};
// findAndModify is a function that takes a single object as an argument,
// and that's what we created above
result = Rooms.findAndModify(findAndModifyArgument);
你的意思是,like
回合
可以是第一回合
或最后一次遭遇
,例如?回合就像游戏中的第一轮问题。所以我想要一些类似的答案:{1:{….请用您想要的实际文档更新您的问题第一个代码块就是我想要的。我当然手动键入了它,所以如果有任何结构问题,这是我的错,但我认为它显示了我想要的。查看如何代替字段名“round”我有动态分配的号码?你用$elemMatch
干什么?我需要用一个数字替换“round”字段名,使其看起来像:$addToSet:{“answers”:{“1”:{userId:“ASDF”…我发现我的问题中有一些令人困惑的代码,可能会误导您。希望编辑能澄清问题。好吧,首先让我问您为什么要这样构造数据。为什么要使用唯一的密钥名(1、2、3等)?游戏有几轮的问题,玩家会回答。我之所以采用这种方式构建游戏,是因为它可以让我更容易地通过在结构中嵌入少量信息来更新UI,而不是单独的“一轮”字段,需要执行额外的查询来聚合和移动数据。嗯,结构与我在第一个代码块中想要的不同。但是,我看到了您在那里做了什么。如果我删除答案:part并只执行$addToSet:createObject,我就可以像我想要的那样在编号字段下的数组中获得这一轮的所有答案。G够了,谢谢你的帮助!