O que você precisa não é possível usando uma única atualização sem alguma lógica do lado do aplicativo. Observe que o upsert como um recurso não é relevante para esse problema específico, a menos que você queira criar automaticamente novos documentos de widget se nenhum existir com o nome fornecido.
O problema que você está enfrentando é que não há nenhuma funcionalidade que permita fazer duas atualizações diferentes dependendo da existência de um elemento de array. Suas únicas duas opções são:
- Encontre o item, determine a existência de propriedades relevantes, compile uma atualização apropriada com suas propriedades novas ou alteradas e execute-a. Isso vem com a importante desvantagem de que este não é um método seguro de simultaneidade. Em outras palavras, se dois serviços da Web tentarem isso ao mesmo tempo, um poderá substituir as alterações um do outro.
- Crie documentos de nível superior de propriedades de widgets em vez de incorporados. Permite que você use upserts para fazer o que quiser. A desvantagem óbvia é que essa não é uma opção muito boa em termos de design de esquema. Você não obteria automaticamente todas as propriedades se buscasse um widget, por exemplo.