简体   繁体   中英

Meteor disobeys $exists from Mongo

I have two collections, one called villages, and one called cities. I loop through every village and run it against my other collection to find the nearest city. Then, I add a field city: cityName to my villages collection. This will let me know which city each village is close to.

var cursor = Villages.find({city: {$exists: 0}});

cursor.forEach(function(village) {
    var lat = district.loc.latitude;
    var long = district.loc.longitude;
    var city = Cities.find({ loc: {$near: [lat,long],
                                   $maxDistance: 2}},
                           {fields: {name: 1, _id: 0}},
                           {limit: 1});

    city.forEach(function(nearestCity) {
        Villages.update({name: village.name}, 
                        {$set: {city: nearestCity.name}});
    });

});

Every bit of this worked the first time I ran it. Starting from the top of my list it went through and over time added about 40,000 city fields to my villages collection. My laptop did computer things, connection was lost, I tried to run it again. Instead of starting where it left off, it begins at the top of the collection again, regardless of the fact that the city field exists in those entries.

I traced the different values and it still works properly, just not on the right documents. When I removed the field from one of the first documents, the count of the cursor went up by 1 until it went down the list and passed over it. Then the count decreased again.

My question is this: Why would a cursor that returns the correct number of documents operate on the wrong ones?

The problem was that I did not have all unique names for my documents. Changing it to update based on the _id value fixed my issue. The app found (as an example) Wembley CA, saw it was closest to Grande Prairie CA, but then applied that information to whichever of Wembley GB or AU the collection decided to surface for me. This means everything was working correctly, but it would still find the same documents without city values because it was only giving city values to their homonymous siblings. My final script was

var cursor = Villages.find({city: {$exists: 0}});

cursor.forEach(function(village) {
    var lat = village.loc.latitude;
    var long = village.loc.longitude;
    var city = Cities.find({loc: {$near: [lat,long], $maxDistance: 2}}, 
                            {fields: {name: 1, _id: 0}} 
                            ).fetch();

    if(city.length == 0) //If no cities are nearby, I let it pick itself
    {
        city = [{name: village.name}];
    }

    Villages.update({_id: village._id}, {$set: {city: city[0].name}});

});

I used find().fetch() rather than just find() . This let me access a single document and its values more easily. This gave me access to the _id field which I used to reference the appropriate document and solve my problem.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM