最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

mongodb - How to update a document in a forEach-loop in Javascript using Monk? - Stack Overflow

programmeradmin2浏览0评论

First the structure of my documents:

{
  "_id": "541a8bea74123744b371d38e",
  "geometry": {
    "type": "Point",
    "coordinates": [
      5.3435,
      51.69554
    ]
  },
  "type": "Feature",
  "properties": {
  }
}

The thing is I want to add a field using the update function in a forEach loop. The loop works, I can iterate over every document in the collection but the update function does nothing. This is what I have:

var counter = 0;
collection.find({}, {
    stream: true
  })
  .each(function(doc) {
    counter++;
    var hash = geohash.encode(doc.geometry.coordinates[1], doc.geometry.coordinates[0], precision = 9);
    console.log("id: " + doc._id + " hash: " + hash + " counter= " + counter);
    collection.update({
        _id: doc._id
      }, {
        $set: {
          "properties.geohash.precision9": hash
        }
      },
      function(err) {
        if (err) console.log(err);
      }
    );
  })
  .error(function(err) {
    // handle error
    console.log(err);
  })
  .success(function(doc) {
    // final callback
    console.log("added geohash");
    res.send({
      objects: doc
    });
  });

Where am I wrong?

First the structure of my documents:

{
  "_id": "541a8bea74123744b371d38e",
  "geometry": {
    "type": "Point",
    "coordinates": [
      5.3435,
      51.69554
    ]
  },
  "type": "Feature",
  "properties": {
  }
}

The thing is I want to add a field using the update function in a forEach loop. The loop works, I can iterate over every document in the collection but the update function does nothing. This is what I have:

var counter = 0;
collection.find({}, {
    stream: true
  })
  .each(function(doc) {
    counter++;
    var hash = geohash.encode(doc.geometry.coordinates[1], doc.geometry.coordinates[0], precision = 9);
    console.log("id: " + doc._id + " hash: " + hash + " counter= " + counter);
    collection.update({
        _id: doc._id
      }, {
        $set: {
          "properties.geohash.precision9": hash
        }
      },
      function(err) {
        if (err) console.log(err);
      }
    );
  })
  .error(function(err) {
    // handle error
    console.log(err);
  })
  .success(function(doc) {
    // final callback
    console.log("added geohash");
    res.send({
      objects: doc
    });
  });

Where am I wrong?

Share Improve this question edited Oct 29, 2014 at 14:52 Cerbrus 73k19 gold badges136 silver badges150 bronze badges asked Oct 29, 2014 at 14:50 justauserjustauser 211 gold badge1 silver badge5 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 1

A working code in MongoDb shell

db.collection.find().forEach(function(item)
{
    var hash = ....;
    item.properties.geohash.precision9 = hash;
    db.collection.save(item);
})

I believe with some small changes u can use it with monk

I believe your issue is with your chosen schema. Properties is a subdocument and items stored in it are accessible with the '.', but then you're attempting to set a property of another subdocument geohash. Monk is a very lightweight MongoDB driver and will not support this many levels of subdocuments. I suggest changing your schema to the following:

{
  "_id": "541a8bea74123744b371d38e",
  "geometry": {
   "type": "Point",
   "coordinates": [
     5.3435,
     51.69554
   ]
 },
 "type": "Feature",
 "properties": {
 },
"geohash": {
  "precision9": "somevalue"
 }
}

I would try to flatten out the document structure by eliminating subdocuments. In my opinion having a subdocument called properties is redundant because information about the current document pertains directly at the parent level. Unless I am miss understanding something about your data. If that is the case, please provide more documents stored in your database particularly ones that have values for percision9 or other 3 deep properties.

One thing you might be able to do, although a bit ugly, is to use an additional variable to build the subdocument and assign the value 'hash' and then set properties equal to that new variable. This would overwrite anything previously stored in properties unless you handled it properly:

var newProperties = {
 geohash: {
  presision9: hash
 }
}

collection.update({
        _id: doc._id
      }, {
        $set: {
          "properties": newProperties
        }
      },
      function(err) {
        if (err) console.log(err);
      }
    );
  })

发布评论

评论列表(0)

  1. 暂无评论