我正在尝试使用 how to update sequence number in mongodb safely 中描述的 PHP 版本的查询来更新多个数组元素。
其中描述了查询:
db.so.update(
{ _id: new ObjectId("4f55e7ba362e2f2a734c92f8")},
{ $set : { 'subs.1.order' : 3, 'subs.2.order' : 2 } }
);
我正在构建一个查询以将“订单”字段添加到我的文档中
{
"_id": {
"$oid": "5209acfd0de2316335000001"
},
"bookListId": "116ad5af-7cc6-4652-9bb3-aea852e584e8",
"favoriteBook": [
{
"title": "One Favorite Book",
},
{
"title": "Another Favorite Book",
},
{
"title": "A Third Favorite Book",
}
]
}
..我用 PHP 用
$criteria = array('bookListId' => $bookListId);
$favoriteBookOrder = array();
for($i=0;$i<sizeof($order);$i++) {
$key = 'favoriteBook.'.($i+1).'.order';
$val = $order[$i];
$favoriteBookOrder[] = array($key=>intval($val));
}
$setFavoriteBookOrder = array('$set' => $favoriteBookOrder);
$collection->update($criteria, $setFavoriteBookOrder);
但这不会产生任何结果,因为查询没有正确的数组组织..
error_log(json_encode($setupdated));
输出
{"$set":[{"favoriteBook.1.order":2},{"favoriteBook.2.order":1},{"favoriteBook.3.order":3}]}
如果您注意到其中有太多引号、整个数组周围的方括号以及每个项目周围的大括号。我相信这是导致错误的原因:
"Invalid modifier specified: $set"
在 PHP 中构建数组的正确语法是什么?谢谢!
编辑
这是修复
$favoriteBookOrder[] = array($key=>intval($val));
should be
$favoriteBookOrder[$key] = intval($val);
我还从 $i 中删除了 +1,因为 Mongo 索引是基于 0 的
现在正确查询
{"$set":{"favoriteBook.0.order":1,"favoriteBook.1.order":2,"favoriteBook.2.order":3}}
最佳答案
为了使查询正常工作,您必须更改一行:
$favoriteBookOrder[] = array($key=>intval($val));
到
$favoriteBookOrder[$key] = intval($val);
但我认为你不会对结果感到满意,因为它会是这样的:
"favoriteBook" : {
"0" : { "order" : NumberLong(123) },
"1" : { "order" : NumberLong(321) },
"2" : { "order" : NumberLong(456) }
}
我建议你这样重写代码:
for($i=0;$i<sizeof($order);$i++)
$favoriteBookOrder[$i]['order'] = $order[$i];
$setupdated = array('$set' => ['favoriteBookOrder' => $favoriteBookOrder]);
你会得到:
"favoriteBookOrder" : [
{ "order" : NumberLong(123) },
{ "order" : NumberLong(321) },
{ "order" : NumberLong(456) }
]
附言您可以使用 $pushAll 修饰符代替 $set,它可能更适合您。
关于Mongo $set order 语句的 PHP 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18201051/
我脑子里浮现出一些关于一种新编程语言的想法,所以我想我会尝试实现它。一位friend建议我尝试使用Treetop(Rubygem)来创建一个解析器。Treetop的文档很少,我以前从未做过这种事情。我的解析器表现得好像有一个无限循环,但没有堆栈跟踪;事实证明很难追踪到。有人可以指出入门级解析/AST指南的方向吗?我真的需要一些列出规则、常见用法等的东西来使用像Treetop这样的工具。我的语法分析器在GitHub上,以防有人希望帮助我改进它。class{initialize=lambda(name){receiver.name=name}greet=lambda{IO.puts("He
所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择
在Ruby类中,我重写了三个方法,并且在每个方法中,我基本上做同样的事情:classExampleClassdefconfirmation_required?is_allowed&&superenddefpostpone_email_change?is_allowed&&superenddefreconfirmation_required?is_allowed&&superendend有更简洁的语法吗?如何缩短代码? 最佳答案 如何使用别名?classExampleClassdefconfirmation_required?is_a
可能已经问过了,但我找不到它。这里有2个常见的情况(对我来说,在编程Rails时......)用ruby编写是令人沮丧的:"astring".match(/abc(.+)abc/)[1]在这种情况下,我得到一个错误,因为字符串不匹配,因此在nil上调用[]运算符。我想找到的是比以下内容更好的替代方法:temp="astring".match(/abc(.+)abc/);temp.nil??nil:temp[1]简而言之,如果不匹配,则简单地返回nil而不会出错第二种情况是这样的:var=something.very.long.and.tedious.to.writevar=some
我注意到类定义,如果我打开classMyClass,并在不覆盖的情况下添加一些东西我仍然得到了之前定义的原始方法。添加的新语句扩充了现有语句。但是对于方法定义,我仍然想要与类定义相同的行为,但是当我打开defmy_method时似乎,def中的现有语句和end被覆盖了,我需要重写一遍。那么有什么方法可以使方法定义的行为与定义相同,类似于super,但不一定是子类? 最佳答案 我想您正在寻找alias_method:classAalias_method:old_func,:funcdeffuncold_func#similartoca
我正在学习Ruby的基础知识(刚刚开始),我遇到了Hash.[]method.它被引入a=["foo",1,"bar",2]=>["foo",1,"bar",2]Hash[*a]=>{"foo"=>1,"bar"=>2}稍加思索,我发现Hash[*a]等同于Hash.[](*a)或Hash.[]*一个。我的问题是为什么会这样。是什么让您将*a放在方括号内,是否有某种规则可以在何时何地使用“it”?编辑:我的措辞似乎造成了一些困惑。我不是在问数组扩展。我明白了。我的问题基本上是:如果[]是方法名称,为什么可以将参数放在括号内?这看起来几乎——但不完全是——就像说如果你有一个方法Foo.d
我正在尝试使用ruby编写一个双线程客户端,一个线程从套接字读取数据并将其打印出来,另一个线程读取本地数据并将其发送到远程服务器。我发现的问题是Ruby似乎无法捕获线程内的错误,这是一个示例:#!/usr/bin/rubyThread.new{loop{$stdout.puts"hi"abc.putsefsleep1}}loop{sleep1}显然,如果我在线程外键入abc.putsef,代码将永远不会运行,因为Ruby将报告“undefinedvariableabc”。但是,如果它在一个线程内,则没有错误报告。我的问题是,如何让Ruby捕获这样的错误?或者至少,报告线程中的错误?
这个问题在这里已经有了答案:WhatisRuby'sdouble-colon`::`?(12个答案)关闭8年前。什么是::?@song||=::TwelveDaysSong.new
在添加一些空格以使代码更具可读性时(与上面的代码对齐),我遇到了这个:classCdefx42endendm=C.new现在这将给出“错误数量的参数”:m.x*m.x这将给出“语法错误,意外的tSTAR,期待$end”:2/m.x*m.x这里的解析器到底发生了什么?我使用Ruby1.9.2和2.1.5进行了测试。 最佳答案 *用于运算符(42*42)和参数解包(myfun*[42,42])。当你这样做时:m.x*m.x2/m.x*m.xRuby将此解释为参数解包,而不是*运算符(即乘法)。如果您不熟悉它,参数解包(有时也称为“spl
我想从then子句中访问case语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案