Обновить документы из каждого значения входного массива - PullRequest
0 голосов
/ 13 июня 2018

У меня есть JSON с двумя ключами: идентификатор и имя.Мне нужен способ вставить этот идентификатор в мою коллекцию (querys.project.name), когда имя в нем и в JSON совпадают.

Пример моего JSON:

var projectsMysql = [
{
    "id" : 1,
    "name" : "Something"
},
{
    "id" : 5,
    "name" : "Something else"
},
{
    "id" : 50,
    "name" : "Some name"
}]

ив моей коллекции около 60 документов, подобных этому:

  {
  "_id" : ObjectId("58e42bf30a34d641be6c25c2"),
  "folio" : "R-666-69",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Something else"
      // "projectsMysql_id" : 5 THIS SHOULD BE PLACED HERE
  },
}

Я написал функцию для Node.js, но теперь мне нужно запустить ее непосредственно в оболочке mongo, я прочитал, что мне нужно использовать cursor.forEach(), но я не смог найти способ сделать это, это моя функция:

projectsMysql
.forEach(function(project){
var query = {
  name: project.name
}
db.getCollection('requests')
  .find(query)
  .exec(function(err, response){
    if (err) {
      return 
    }
    if (response) {
      db.getCollection('requests')
        .update({id: response.id}, {$set: {
          'project.projectsMysql_id': project.id
           console.log("element inserted"); 
        }})
        .exec(function(err){
        });
    }
  });
});

Можете ли вы указать мне правильное направление?

1 Ответ

0 голосов
/ 13 июня 2018

Здесь вы хотите получить bulkWrite(), где вместо фактического выполнения update() для каждого документа в массиве projectsMysql вы фактически просто создаете «один» оператор, состоящий из «множественных»обновления, которые отправляются на сервер и обновляют соответствующие документы:

db.getCollection('requests').bulkWrite(
  projectsMysql.map(({ id, name }) => 
    ({ "updateOne": {
      "filter": { "project.name": name },
      "update": { "$set": { "project.id": id } }
    }})
  )
)

Если вы ожидаете, что «несколько документов» будут соответствовать условию, просто переключитесь на updateMany:

db.getCollection('requests').bulkWrite(
  projectsMysql.map(({ id, name }) => 
    ({ "updateMany": {
      "filter": { "project.name": name },
      "update": { "$set": { "project.id": id } }
    }})
  )
)

Ваш массив уже находится в памяти, поэтому на самом деле нет никакого смысла делать какие-либо другие «итерации», и вы можете просто .map() свойства для операторов updateOne (или updateMany) ивыдать их всех в одном заявлении.Обновления фактически обрабатываются только там, где есть «совпадение» и действительно, где есть что обновить, поскольку существующие значения будут оставлены в покое, используя $set.


ToПродемонстрируйте, учитывая следующие документы:

{
  "folio" : "R-666-69",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Something else"
  }
},
{
  "folio" : "R-666-67",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Some name"
  }
},
{
  "folio" : "R-666-68",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Some name"
  }
}
{
  "folio" : "R-666-64",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Something"
  }
},
{
  "folio" : "R-666-65",
  "alias_purchase" : "Deal",
  "project" : {
      "description" : "",
      "name" : "Different"
  }
}

Следующее обновление:

var projectsMysql = [
{
    "id" : 1,
    "name" : "Something"
},
{
    "id" : 5,
    "name" : "Something else"
},
{
    "id" : 50,
    "name" : "Some name"
}]

db.getCollection('requests').bulkWrite(
  projectsMysql.map(({ id, name }) => 
    ({ "updateMany": {
      "filter": { "project.name": name },
      "update": { "$set": { "project.id": id } }
    }})
  )
)

Возвращает ответ:

{
        "acknowledged" : true,
        "deletedCount" : 0,
        "insertedCount" : 0,
        "matchedCount" : 4,
        "upsertedCount" : 0,
        "insertedIds" : {

        },
        "upsertedIds" : {

        }
}

И соответственно изменяет сопоставленные документы:

{
        "_id" : ObjectId("5b206a48f7fa0c655d90157a"),
        "folio" : "R-666-69",
        "alias_purchase" : "Deal",
        "project" : {
                "description" : "",
                "name" : "Something else",
                "id" : 5
        }
}
{
        "_id" : ObjectId("5b206a48f7fa0c655d90157b"),
        "folio" : "R-666-67",
        "alias_purchase" : "Deal",
        "project" : {
                "description" : "",
                "name" : "Some name",
                "id" : 50
        }
}
{
        "_id" : ObjectId("5b206a48f7fa0c655d90157c"),
        "folio" : "R-666-68",
        "alias_purchase" : "Deal",
        "project" : {
                "description" : "",
                "name" : "Some name",
                "id" : 50
        }
}
{
        "_id" : ObjectId("5b206a48f7fa0c655d90157d"),
        "folio" : "R-666-64",
        "alias_purchase" : "Deal",
        "project" : {
                "description" : "",
                "name" : "Something",
                "id" : 1
        }
}
{
        "_id" : ObjectId("5b206a48f7fa0c655d90157e"),
        "folio" : "R-666-65",
        "alias_purchase" : "Deal",
        "project" : {
                "description" : "",
                "name" : "Different"
        }
}
...