Как я могу сгруппировать предметы близко друг к другу, не зная распределения? - PullRequest
0 голосов
/ 26 января 2019

Я готовлю некоторые данные о ценах на проданные квартиры для регрессионного анализа.Одна категория - это улица, на которой расположены дома, но некоторые улицы имеют очень разные площади, поэтому я хочу сделать категорию с комбинацией года постройки и названия улицы.

Broadway 1910
Broadway 2001

Например, моя проблема заключается в том, что иногдастроительство продолжается в течение нескольких двух лет.Данные из Швеции, известной огромными централизованными жилищными проектами.Я бы хотел как-то сгруппировать эти дома.Это мой текущий код.Я знаю, что он не очень эффективен, но он будет работать только один раз для небольшого набора данных.

(async () =>{
    let client;
    try {
        client = await MongoClient;
        let collection = client.db("booliscraper").collection("sold");
        let docs = await collection.find();
        await docs.forEach((sale) => {
            sale.street = sale.location.address.streetAddress.split(/[0-9]/)[0] + sale.location.namedAreas[0]
            sale.streetYear = sale.street+" "+sale.constructionYear

            log(sale);
            collection.replaceOne({_id: ObjectId(sale._id)}, doc)
        });


    client.close(); 

  } catch(err) {
    log(err)
  }
})()

1 Ответ

0 голосов
/ 26 января 2019

Как вы правильно сказали, ваш текущий код неэффективен, когда речь идет о работе с огромными наборами данных, поэтому вместо нескольких обращений к серверу для выполнения replaceOne в цикле forEach вы можете создать агрегированный запрос, который вычисляет поля категорий, которые вы хотите с помощью конвейера $ group, и поместите документы, попадающие в эти категории, в массив, который вы позже будете использовать для массового обновления.

Для массового обновления вы можете использовать метод bulkWrite для коллекции, которая будет иметь несколько операций updateMany.

Следующая операция показывает приведенную выше интуицию на практике:

(async () => {
    try {
        let client = await MongoClient;
        let collection = client.db("booliscraper").collection("sold");
        let pipeline = [
            { '$group': { 
                '_id': {
                    'street': { 
                        '$concat': [
                            { 
                                '$arrayElemAt': [
                                    { '$split': [
                                        '$location.address.streetAddress', 
                                        /[0-9]/
                                    ] },
                                    0
                                ]
                            }, 
                            {  '$arrayElemAt': [ '$location.namedAreas', 0 ] },
                        ] 
                    },
                    'streetYear': { '$concat': ['$street', ' ', '$constructionYear']  }
                },
                'ids': { '$push': '$_id' }
            } }
        ]
        let docs = await collection.aggregate(pipeline);
        let ops = docs.map(({ _id, ids }) => ({
            'updateMany': {
                'filter': { '_id': { '$in': ids } },
                'update': { '$set': { 
                    'street': _id.street, 'streetYear': _id.streetYear 
                } }
            }
        }));
        let result = await collection.bulkWrite(ops);

        log(result)

        client.close()

    } catch(err) {
        log(err)
    }
})()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...