моя структура документов такая:
{
'name': 'name1',
'sources': [
{
'site': 'www.example1.com',
'first_seen_date': ISODate("2018-04-09T15:43:49.941Z"),
'last_seen_date': ISODate("2018-04-09T15:43:49.941Z")
},
{
'site': 'www.example2.com',
'first_seen_date': ISODate("2018-02-09T15:43:49.941Z"),
'last_seen_date': ISODate("2018-04-10T15:43:49.941Z")
}
]
}
Я хочу найти документы с определенным «именем» и «сайтом» - если они существуют, чтобы обновить last_seen_date. если существует только имя, а сайт не существует - добавьте сайт в массив с site, first_seen_date, last_seen_date. я могу сделать это одним запросом? Единственное решение, которое я могу придумать, содержит два разных запроса.

Вы можете использовать 2 запроса updateOne, один с $ne и $set, а другой с $pushодин за другим. Это все равно сделает операцию "атомарной", даже если вы используете более 1 узла приложения:
db.test.updateOne(
{
name: 'name1',
'sources.site': 'www.example3.com'
},
{
$set: {
'sources.$.last_seen_date': new Date()
}
}
)
db.test.updateOne(
{
name: 'name1',
'sources.site': {$ne: 'www.example3.com'}
},
{
$push: {
sources: {
site: 'www.example3.com',
first_seen_date: new Date(),
last_seen_date: new Date(),
}
}
}
)
К сожалению, $addToSet по объектному ключу недоступен. Это могло бы значительно облегчить эту проблему. Похоже, что эта функция давно открыта:
https://jira.mongodb.org/browse/SERVER-13841
Различные запросы или язык по вашему выбору для выполнения всего в едином потоке с использованием логики.