我已经在聚合框架中浏览了MongoDB $ literal ,但我不明白它可以在哪里使用?更重要的是,为什么需要它?
MongoDB官方文档中的示例
db.records.aggregate( [
{ $project: { costsOneDollar: { $eq: [ "$price", { $literal: "$1" } ] } } }
])
使用$ literal代替上面的例子,为什么我不能使用如下?
db.records.aggregate( [
{ $project: { costsOneDollar: { $eq: [ "$price", "$1" ] } } }
] )
还提供一些其他示例,显示 $ literal 的最佳(或有效)用法。
答案 0 :(得分:3)
对于你的基本情况,我认为documentation是相当自我解释的:
在表达式中,美元符号$计算为字段路径;即提供对场地的访问。例如,$ eq表达式$ eq:[" $ price"," $ 1" ]在名为price的字段中的值与文档中名为1的字段中的值之间执行相等性检查。
因此,$
被保留用于评估文档中的字段路径值,因此可以认为这实际上是在寻找"字段"在文档中命名为1
。因此,实际的比较可能在名为" price"因为没有名为" 1"然后,对于每个文档,这将被视为null
,因此被视为false
。
另一方面,该领域"价格"实际上有一个等于"$1"
的值,那么$literal
的使用允许"值" (而不是字段路径引用)要考虑。因此"字面意思"。
运营商实际上已经存在了一段时间(实际上是MongoDB 2.2)但是在$const
的幌子下,虽然没有被分类仍然是基本的运算符,$literal
实际上只是一个& #34;别名"为此。
用法主要是并且一直用于expression需要具有某些特定值"按照管道中的指示。采取这个简单的声明:
{ "$project": { "myField": "one" } }
因此,出于各种原因,您可能希望这样做,并基本上返回一个"字面值"这种说法中的价值。但是如果你尝试过,它会导致错误,因为它基本上不会解析为"字段路径"或者boolean
字段选择条件,这里需要。所以,如果您改为使用:
{ "$project": { "myField": { "$literal": "one" } } }
然后你有" myField"值为"一个"就像你要求的那样。
其他用法更具历史意义,例如:
{ "$project": { "array": { "$literal": ["A","B","C" ] } } },
{ "$unwind": "$array" },
{ "$group": {
"_id": "$_id",
"trans": { "$push": {
"$cond": [
{ "$eq": [ "$array", "A" ] },
"$fieldA",
{ "$cond": [
{ "$eq": [ "$array", "B" ] },
"$fieldB",
"$fieldC"
]}
]
}}
}}
可能更现代地被替换为:
{ "$project": {
"trans": {
"$map": {
"input": ["A","B","C"],
"as": "el",
"in": {
"$cond": [
{ "$eq": [ "$$el", "A" ] },
"$fieldA",
{ "$cond": [
{ "$eq": [ "$$el", "B" ] },
"$fieldB",
"$fieldC"
]}
]
}
}
}
}}
作为根据位置将所选字段移动到数组中的构造,区别在于" array"和$literal
字段赋值是必要的,但作为"输入"参数plain数组表示法就好了。
所以一般情况是:
需要保留$
之类的内容作为匹配的值
其中有一个特定值要作为字段赋值注入,而不是作为另一个运算符表达式的参数。
答案 1 :(得分:1)
您提供的$1
示例会尝试将price
字段与1
字段进行比较。通过指定$literal
运算符,您可以告诉MongoDB它是确切的字符串"$1"
。如果您想在代码中使用MongoDB函数名作为字段名,或者甚至使用查询片段作为字段值,则可能也是如此。