文档子数组存储为 Mongo 中第一个条目的重复值

Posted

技术标签:

【中文标题】文档子数组存储为 Mongo 中第一个条目的重复值【英文标题】:Document sub-arrays stored as duplicate values of the first entry in Mongo 【发布时间】:2014-12-09 22:31:15 【问题描述】:

我在尝试更新任何文档子数组时使用 angular-fullstack 和 Mongolabs,存储在 Mongolabs 中的值仅显示为数组中第一个元素的重复值。

Mongoose 模式设置为

techspecs: [label: String, value: String, _id: false],

当更新有效负载时显示正确并包含不同的值,例如

techspecs: [label: "Dimensions", value: "1200x800mm", label:"Capacity", value: "532 l"]

但是在 Mongolabs 中,值存储为

"techspecs": [
        
            "label": "Dimensions",
            "value": "1200x800mm"
        ,
        
            "label": "Dimensions",
            "value": "1200x800mm"
        
    ],

如果我有更多的值对,它只会存储第一个元素的多个副本。

更新是通过工厂服务使用 $resource 完成的

angular.module('prototypeMeanApp')
  .factory('productAPI', ['$resource', function($resource) 
      return $resource('api/products/:id', id: '@_id', 
        'update':  method:'PUT',
        'create':  method:'POST',
        'query' : method:'GET', isArray:true
      );         
    
]);

在控制器中,它通过以下函数进行更新

$scope.updateProduct = function(form) 
  $scope.submitted = true;      
  var pId = $scope.product._id;
  if(form.$valid) 
    productAPI.update(id: pId, 
          _id: pId,
          categoryid: $scope.currentcat[0]._id,
          brand: $scope.product.brand,
          model: $scope.product.model,
          heading: $scope.product.heading,
          description: $scope.product.description,
          price: $scope.product.price,
          techspecs: $scope.product.techspecs,
          lastmodified: Date.now()   
    ).$promise.then(function()     
      console.log('Product updated');          
    , function(err) 
      err = err.data;
      $scope.errors = ;
      angular.forEach(err.errors, function(error, field) 
        form[field].$setValidity('mongoose', false);
        $scope.errors[field] = error.message;            
      );
    );

在视图中

<div class="form-group" data-ng-repeat="techspec in product.techspecs">
    <label class="control-label hidden-xs col-sm-3">Tech Spec #$index+1</label>
    <div class="col-sm-4 col-md-3">
        <div class="controls">                                                     
            <input type="text" data-ng-model="techspec.label" class="form-control" placeholder="Label" />
        </div>
    </div>
    <div class="col-sm-4 col-md-3">
        <div class="controls">                                         
            <input data-ng-model="techspec.value" type="text" class="form-control"  placeholder="Value"  />
        </div>    
    </div>
</div>

【问题讨论】:

【参考方案1】:

我最终使用 mean.io 进行了一个简单的测试,以验证这是否可行,并且 Mean.io 成功地将文档子数组存储到 Mongo 中。在此之后,我比较了 angular-fullstack 和 mean.io 的源代码和实现方法,看看有什么不同。

最后竟然是更新函数中使用的lodash方法。

angular-fullstack 使用 _.merge 而 mean.io 在将 angular-fullstack 代码更改为使用 _.extend 后使用 _.extend,子数组已正确存储到 MongoDB 中

对于其他使用 angular-fullstack 的人。编辑您的服务器端点控制器,例如服务器/api/products/product.controller.js

然后找到更新函数并将 _.merge 替换为 _.extend 例如

exports.update = function(req, res) 
  if(req.body._id)  delete req.body._id; 
  Product.findById(req.params.id, function (err, product) 
    if (err)  return handleError(res, err); 
    if(!product)  return res.send(404); 
    var updated = _.extend(product, req.body);
    updated.save(function (err) 
      if (err)  return handleError(res, err); 
      return res.json(200, product);
    );
  );
;

【讨论】:

谢谢!这正是我遇到的问题

以上是关于文档子数组存储为 Mongo 中第一个条目的重复值的主要内容,如果未能解决你的问题,请参考以下文章

给Array本地对象增加一个原型方法,它用于删除数组条目中重复的条目(可能有多个),返回值是一个包含被删除的重复条目的新数组

mongo 介绍

找数组中第K大的数 请教

MongoDB索引

删除重复的数组条目

检查数组中的重复条目,但仅返回重复的值 [重复]