返回字段

时间:2017-08-09 09:25:17

标签: mongodb mongodb-query aggregation-framework

我只是想在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}

  

1 个答案:

答案 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 } }
);