MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Como implemento esta operação de consulta e atualização do mongodb (driver CSharp)?


Se eu essencialmente entendo sua essência, você basicamente quer
  1. Puxe o item que não é necessário de sua matriz de referências
  2. Defina o valor do seu campo de referência principal para o primeiro elemento da matriz alterada

E faça tudo isso em uma atualização sem mover documentos pela rede.

Mas isso infelizmente não pode ser feito. O principal problema com isso é que não há como fazer referência ao valor de outro campo dentro do documento que está sendo atualizado. Mesmo assim, para fazer isso sem iterar, você também precisaria acessar o alterado array para obter o novo primeiro elemento.

Talvez uma abordagem seja repensar seu esquema para realizar o que você deseja. Minha opção aqui seria expandir um pouco seus documentos de referência e remover a necessidade do campo de referência principal.

Parece que a suposição com a qual você está disposto a conviver com as atualizações é que, se a referência removida era a referência principal, você pode simplesmente definir a nova referência principal para o primeiro elemento da matriz. Com isso em mente, considere a seguinte estrutura:
refs: [ { oid: "object1" }, { oid: "object2" }, { oid: "object5", main: true } ]

Ao alterá-los para documentos com um oid propriedade que seria definida para o ObjectId dá a opção de ter uma propriedade adicional no documento que especifica qual é o padrão. Isso pode ser facilmente consultado para determinar qual Id é a referência principal.

Agora considere também o que aconteceria se o documento correspondente a "object5" no campo oid fosse extraído do array:
refs: [ { oid: "object1" }, { oid: "object2" } ]

Então, quando você consulta qual é a main-reference de acordo com a lógica anterior, você aceita o primeiro documento na matriz. Agora, é claro, para os requisitos do seu aplicativo, se você quiser definir uma main-reference diferente você acabou de alterar o documento
refs: [ { oid: "object1" }, { oid: "object2", main: true } ]

E agora a lógica permanece para escolher o elemento da matriz que tem a propriedade main como true ocorreria de preferência, e como mostrado acima, se essa propriedade não existir em nenhum documento de elementos, volte para o primeiro elemento.

Com tudo isso digerido, sua operação para extrair todas as referências a um objeto desse array em todos os documentos se torna bastante simples, como feito no shell (o mesmo formato deve se aplicar basicamente a qualquer driver):
db.books.update(
   { "refs.oid": "object5" },
   { $pull: { refs: {oid: "object5"} } }, false, true )

Os dois argumentos extras para a operação de consulta e atualização sendo upsert e multi respectivamente. Neste caso, upsert não faz muito sentido, pois queremos apenas modificar os documentos que existem, e multi significa que queremos atualizar tudo o que corresponde. O padrão é alterar apenas o primeiro documento.

Naturalmente eu encurtei toda a notação, mas é claro que os valores podem ser ObjectIds reais conforme sua intenção. Também parecia razoável presumir que seu uso principal do main-reference é uma vez que você recuperou o documento. Definindo uma consulta que retorna a main-reference seguindo a lógica que foi delineada deve ser possível, mas do jeito que está eu digitei muito aqui e preciso fazer uma pausa para o jantar :)

Acho que isso apresenta um caso que vale a pena repensar seu esquema para evitar iterações diretas para o que você deseja alcançar.