我只是想在SQL中编写一个mongo查询:
SELECT LENGTH(binaryBody) AS bodyLength FROM documents;
为此我想我必须使用find方法的投影。
db.documents.find(
{<query>},
{ bodyLength: {$size: 'body'}}
);
但是怎么做?
错误:错误: {“waitedMS”:NumberLong(0),“ok”:0,“errmsg”:
“不支持的投影选项:bodyLength:{$ size:\”body \“}”, “code”:2}
答案 0 :(得分:3)
.find()
不会“改变”以任何方式返回的文件。您只能在投影中“包含”或“排除”。
“改变”的唯一内容是.aggregate()
或.mapReduce()
。
对于.aggregate()
,需要MongoDB 3.4用于$strLenCP
或$strLenBytes
,但通常是指前者:
db.documents.aggregate([
{ "$project": {
"bodyLength": { "$strLenCP": "$body" }
}}
])
.mapReduce()
db.documents.mapReduce(
function() {
emit(this._id, this.body.length)
},
function() { },
{ "out": { "inline": 1 } }
);
实际上在后一种情况下,你也可以迭代光标,并且可能需要除非集合足够小或者你实际上可以输出到另一个集合。
您尝试使用的$size
运算符仅适用于“数组”以返回存在的条目数。同样,它仅适用于使用.aggregate()
方法。
如果您要在字符串中省略space
等字符,则可以应用$split
和$reduce
$concat
:
db.documents.aggregate([
{ "$addFields": {
"bodyLength": {
"$strLenCP": {
"$reduce": {
"input": { "$split": [ "$name", " "] },
"initialValue": "",
"in": { "$concat": [ "$$value", "$$this" ] }
}
}
}
}}
])
或者再次使用mapReduce()
:
db.documents.mapReduce(
function() {
emit(this._id, "".concat.apply(this.body.split(" ")).length)
// Or even
// emit(this._id, this.body.split(" ").reduce((o,e) => o.concat(e),"").length)
},
function() { },
{ "out": { "inline": 1 } }
);