投影阵列中项目阶段操作员的行为 [英] Behaviour of the project stage operator in projecting Arrays
问题描述
我的问题与 this ,但不相似。
My question is closely related to this, but not similar.
我的收藏夹中有一个示例文档:
I have a sample document in my collection:
db.t.insert({"a":1,"b":2});
我的意图是设计一个名为 combined
array 的>,其值分别为 a
和 b
([1,2])。
My intent is to project a field named combined
of type array
with the values of both a
and b
together.([1,2])
.
我只是尝试将 $ project
阶段:
db.t.aggregate([
{$project:{"combined":[]}}
])
MongoDB
引发错误:不允许对象表达式中的字段类型为数组
。
但是当我使用 $ cond
运算符来投影一个数组时,
But when i use a $cond
operator to project an array, the field gets projected.
db.t.aggregate([
{$project:{"combined":{$cond:[{$eq:[1,1]},["$a","$b"],"$a"]}}}
])
我得到o / p: { combined:[ $ a, $ b ]}
。
I get the o/p: {"combined" : [ "$a", "$b" ] }
.
如果您注意到输出,则 a
和 b $ c的值$ c>就像是文字而不是字段路径一样。
If you notice the output, the value of a
and b
are treated as if they were literals and not a field paths.
有人可以向我解释这种现象吗?,当我使条件失败时,
Can anyone please explain to me this behavior?, When i make the condition to fail,
db.t.aggregate([
{$project:{"combined":{$cond:[{$eq:[1,2]},["$a","$b"],"$a"]}}}
])
我得到了预期的输出,其中 $ a
被视为字段路径,因为 $
I get the expected output where $a
is treated as a field path, since $a
is not enclosed as an array element.
推荐答案
我以前也遇到过这个问题,并且这很烦人,但实际上按文字 [ $ a, $ b]
所记录的那样工作;关于不允许的字段类型的第一个错误是...不清楚为什么会抱怨。但是,您必须遵循文档中扩展的 $ project
阶段的语法说明。我会在这里尝试这样做。从 $ project
,
I've run into this before too and it's annoying, but it's actually working as documented for literal ["$a", "$b"]
; the first error about disallowed field type is...not as clear why it complains. You have to follow the description of the grammar of the $project
stage spread out in the documentation, however. I'll try to do that here. Starting at $project
,
$ project阶段具有以下原型形式:
The $project stage has the following prototype form:
{ $project: { <specifications> } }
其规格可以是以下之一:
and specifications can be one of the following:
1. <field> : <1 or true or 0 or false>
2. <field> : <expression>
什么是表达式?来自聚合表达式,
表达式可以包括字段路径和系统变量,文字,表达式对象和运算符。
Expressions can include field paths and system variables, literals, expression objects, and operator expressions.
这些东西分别是什么?字段路径/系统变量应该很熟悉:它是一个字符串文字,以$或$$为前缀。表达式对象的格式为
What are each of those things? A field path/system variable should be familiar: it's a string literal prefixed with $ or $$. An expression object has the form
{ <field1>: <expression1>, ... }
而运算符表达式具有以下形式之一
while an operator expression has one of the forms
{ <operator>: [ <argument1>, <argument2> ... ] }
{ <operator>: <argument> }
获得< operator> $的一些枚举值列表c $ c>。
什么是< argument>
?文档尚不清楚,但是根据我的经验,我认为它是任何表达式,但要遵循给定运算符的语法规则(检查运算符表达式 cond:... $ c
What's an <argument>
? The documentation isn't clear on it, but from my experience I think it's any expression, subject to the syntax rules of the given operator (examine the operator expression "cond" : ...
in the question).
数组只能作为参数列表和文字的容器。文字是文字-不会为字段路径或系统变量评估其内容,这就是为什么 $ cond
中的数组文字参数最终以值 [ $ a, $ b]
。对参数数组中的表达式进行求值。
Arrays fit in only as containers for argument lists and as literals. Literals are literals - their content is not evaluated for field paths or system variables, which is why the array literal argument in the $cond
ends up with the value [ "$a", "$b" ]
. The expressions in the argument array are evaluated.
关于数组是不允许的值类型的第一个错误对我来说有点奇怪,因为数组文字是有效的表达式,因此根据文档,它可以是对象表达式中的值。在将其解析为对象表达式的一部分时,我也没有任何歧义。看起来这只是他们简化解析的规则?您可以使用 $ literal
来躲避它,以放置一个恒定的数组值:
The first error about Array being a disallowed value type is a bit odd to me, since an array literal is a valid expression, so according to the documentation it can be a value in an object expression. I don't see any ambiguity in parsing it as part of an object expression, either. It looks like it's just a rule they made to make the parsing easier? You can "dodge" it using $literal
to put in a constant array value:
db.collection.project([{ "$project" : { "combined" : { "$literal" : [1, 2] } } }])
我希望这有助于解释为什么事情会这样进行。第一次尝试执行 [ $ a, $ b]
之类的操作时,我感到很惊讶,但它没有按预期工作。至少有一个功能可以将字段路径打包到一个数组中。当 $ group
也对有序值对进行查找时,我也找到了它的用途。
I hope this helps explain why things work this way. I was surprised the first time I tried to do something like [ "$a", "$b" ]
and it didn't work as I expected. It'd be nice if there were a feature to pack field paths into an array, at least. I've found uses for it when $group
ing on ordered pairs of values, as well.
有一个JIRA票证, SERVER-8141 ,请求 $ array
运算符可帮助处理此类情况。
There's a JIRA ticket, SERVER-8141, requesting an $array
operator to help with cases like this.
这篇关于投影阵列中项目阶段操作员的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!