有没有办法在mongodb中获取对象字段的长度?

有没有办法在mongodb中获取对象字段的长度?,mongodb,mapreduce,mongodb-query,aggregation-framework,Mongodb,Mapreduce,Mongodb Query,Aggregation Framework,我在MongoDB中有以下对象: [ { "name": "pencil", "purchase_record": { "1":"$900", "2":"$1000", "3":"$1100", "4":"$1200" } }, { "name": "pen", "purchase_record":

我在
MongoDB
中有以下对象:

[
    {
        "name": "pencil",
        "purchase_record": {
            "1":"$900",
            "2":"$1000",
            "3":"$1100",
            "4":"$1200"
        }
    },
    {
        "name": "pen",
        "purchase_record": {
            "1":"$1000",
            "2":"$1200",
            "3":"$900",
            "4":"$1100",
            "5":"$1100"
        }
    }
]

是否有一种获取每个记录的<代码>购买记录>代码>的长度?

< P>你应该考虑改变你的文档结构,使其成为代码>购买记录>代码>一个如JohnnyHK所指出的数组。最好的方法是使用操作

var bulk=db.xx.initializeUnderedBulkop();
var计数=0;
db.xx.find().forEach(函数(doc){
var采购记录=单据采购记录;
var newRecord=[];
for(采购记录中的var键){
if(Object.prototype.hasOwnProperty.call(购买记录,键))
push({'units':key,'price':purchase\u record[key]});
} 
bulk.find({'u-id':doc.\u-id}).updateOne({
“$set”:{“购买记录”:newRecord});
计数++;
如果(计数%300==0){
//每300次操作执行一次
bulk.execute();
bulk=db.xx.initializeUnderedBulkop();
} 
})
//清理队列
如果(计数>0)bulk.execute();
执行此操作后,您的文档如下所示:

{
“_id”:ObjectId(“565aad654036f6520c25a9bb”),
“名称”:“铅笔”,
“采购记录”:[
{
“单位”:“1”,
“价格”:“$900”
},
{
“单位”:“2”,
“价格”:“$1000”
},
{
“单位”:“3”,
“价格”:“$1100”
},
{
“单位”:“4”,
“价格”:“$1200”
}
]
}
{
“_id”:ObjectId(“565aad654036f6520c25a9bc”),
“名称”:“笔”,
“采购记录”:[
{
“单位”:“1”,
“价格”:“$1000”
},
{
“单位”:“2”,
“价格”:“$1200”
},
{
“单位”:“3”,
“价格”:“$900”
},
{
“单位”:“4”,
“价格”:“$1100”
},
{
“单位”:“5”,
“价格”:“$1100”
}
]
}

现在,您可以使用该方法访问文档的聚合管道并返回“购买记录”

db.xx.aggregate([
{'$project':{
“_id”:0,
“名称”:1,
'size_purchase_record':{'$size':'$purchase_record'}
}} 
])
返回:

{“名称”:“铅笔”,“大小\购买\记录”:4}
{“名称”:“笔”,“大小\购买\记录”:5}
您始终可以使用以下命令将“购买记录”字段添加到结果中:
“购买记录”:1


使用文档当前结构,您可以使用以下方法执行此操作:

var map=function(){
var记录=[];
for(此.purchase\u记录中的var键){
if(Object.prototype.hasOwnProperty.call(this.purchase\u记录,key))
记录。按(键);
} 
var recordsLen=records.length;
emit(this.name,recordsLen);
};
var reduce=函数(键,值){返回值;};
mapReduce(map,reduce,{out:{inline:1}});
返回:

{
“结果”:[
{
“_id”:“笔”,
“价值”:5
},
{
“_id”:“铅笔”,
“价值”:4
}
],
“timeMillis”:1,
“计数”:{
“投入”:2,
“发射”:2,
“减少”:0,
“产出”:2
},
“好”:1
}
或者因为是客户端而效率低下的方法

db.xx.find().map(函数(doc){
返回{
“名称”:doc.name,
“采购记录长度”:Object.key(doc.purchase\u record).length
}; 
})
这将产生:

[
{
“名称”:“铅笔”,
“采购记录”4
},
{
“名称”:“笔”,
“采购记录”:5
}
]

这是一个老问题,但答案很简单,可以从MongoDB 3.4.4版获得

你可以这样做

db.collection.aggregate([
  {
    $project: {
      _id: 0,
      name: 1,
      purchaseCount: {
        $size: {
          "$objectToArray": "$purchase_record"
        }
      }
    }
  }
])
它将给出
采购记录
中的字段计数,结果为

[
  {
    "name": "pencil",
    "purchaseCount": 4
  },
  {
    "name": "pen",
    "purchaseCount": 5
  }
]

上以交互方式查看它,但必须使用map/reduce。你考虑过制作一个数组吗?你能查一下我的答案吗?这个老问题的更新和更简单的答案=)对不起,这是一个老问题,我已经停止使用MongoDB了。此NoSQL数据库导致的问题太多。