Para inserir um documento se não existir é feito por upsert e se você quiser atualizar um documento embutido condicional você precisa do operador $ posicional. Portanto, você precisa usar ambos na consulta para implementar a funcionalidade acima.
Mas no momento o mongodb não suporta upserting com o operador posicional $
Então o que você deseja não é possível fazer isso em uma consulta por enquanto, como alternativa, você pode fazer isso em duas consultas.
Primeiro
db.collection('ratings').update(
{"refid":refid, "votes.ip": ip},
{
$set: { "votes.$.rating":rating }
}
)
Ele retorna o número de documentos atualizados, se for 1 está bom, e se for 0 você precisa enviar um novo registro.
db.collection('ratings').update( { "refid":refid, "votes.ip":{$ne: ip}},
{$push: { votes: { "ip":ip , "rating":rating }}
})
Há também jira ticket para operador posicional e upserting, plz vote nesse problema se você quiser essa funcionalidade no mongodb. Abaixo segue o link do problema
https://jira.mongodb.org/browse/SERVER-3326
(EDITAR :O ticket jira foi fechado com Não farei em junho de 2019)