J'ai une application de ruby on rails en utilisant Mongoid et MongoDB v2.4.6.Requête Mongo Documents incorporés avec une taille
J'ai la structure MongoDB suivante, un record qui embeds_many
fragments:
{
"_id" : "76561198045636214",
"fragments" : [
{
"id" : 76561198045636215,
"source_id" : "source1"
},
{
"id" : 76561198045636216,
"source_id" : "source2"
},
{
"id" : 76561198045636217,
"source_id" : "source2"
}
]
}
Je suis en train de trouver tous les enregistrements de la base de données qui contiennent des fragments avec source_ids en double. Je suis assez sûr que j'ai besoin d'utiliser $ elemMatch car j'ai besoin d'interroger des documents incorporés.
J'ai essayé
Record.elem_match(fragments: {source_id: 'source2'})
qui fonctionne, mais ne limite pas les doublons.
J'ai ensuite essayé
Record.elem_match(fragments: {source_id: 'source2', :source_id.with_size => 2})
qui ne retourne aucun résultat (mais est une requête valide). La requête Mongoid produit est:
selector: {"fragments"=>{"$elemMatch"=>{:source_id=>"source2", "source_id"=>{"$size"=>2}}}}
Une fois cela fonctionne, je dois le mettre à jour pour que la taille soit> 1.
Est-ce possible? J'ai l'impression d'être très proche. Ceci est une opération de nettoyage unique, donc la performance de la requête n'est pas trop un problème (cependant nous avons des millions d'enregistrements à mettre à jour!)
Toute aide est très appréciée!
J'ai été en mesure d'atteindre le résultat souhaité, mais lors des tests, c'est beaucoup trop lent (cela prendra plusieurs semaines à travers notre système de production). Le problème est double requête par enregistrement (nous avons ~ 30 millions d'enregistrements en production).
Record.where('fragments.source_id' => 'source2').each do |record|
query = record.fragments.where(source_id: 'source2')
if query.count > 1
# contains duplicates, delete all but latest
query.desc(:updated_at).skip(1).delete_all
end
# needed to trigger after_save filters
record.save!
end
Wow chouette travail Neil, je ne l'aurais pas fait tout seul! Merci travaille avec brio;) – daveharris