У меня есть рубин на рельсах с использованием Mongoid и MongoDB v2.4.6.Query Mongo Встроенные документы размером
У меня есть следующая структура MongoDB, запись которой embeds_many
фрагментов:
{
"_id" : "76561198045636214",
"fragments" : [
{
"id" : 76561198045636215,
"source_id" : "source1"
},
{
"id" : 76561198045636216,
"source_id" : "source2"
},
{
"id" : 76561198045636217,
"source_id" : "source2"
}
]
}
Я пытаюсь найти все записи в базе данных, которые содержат фрагментов с повторяющимся source_ids.
Я уверен, что мне нужно использовать $ elemMatch, поскольку мне нужно запросить встроенные документы.
Я попытался
Record.elem_match(fragments: {source_id: 'source2'})
который работает, но не ограничивает в дубликатах.
Затем я попытался
Record.elem_match(fragments: {source_id: 'source2', :source_id.with_size => 2})
, который не возвращает никаких результатов (но действительный запрос). Запрос Mongoid производит:
selector: {"fragments"=>{"$elemMatch"=>{:source_id=>"source2", "source_id"=>{"$size"=>2}}}}
После того, как это работает, мне нужно обновить его до $ size is> 1.
Возможно ли это? Мне кажется, что я очень близко. Это одноразовая операция по очистке, поэтому производительность запросов не является большой проблемой (однако у нас есть миллионы записей для обновления!)
Любая помощь очень ценится!
Я смог добиться желаемого результата, но при тестировании он слишком медленный (потребуется много недель, чтобы пройти через нашу производственную систему). Проблема заключается в двойном запросе на запись (у нас есть ~ 30 миллионов записей на производстве).
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
Ничего себе, Нил, я абсолютно не был бы там! Спасибо работает блестяще;) – daveharris