Mongoid 및 MongoDB v2.4.6을 사용하는 레일즈 응용 프로그램에서 루비를 사용하고 있습니다.쿼리 Mongo 임베디드 문서 크기
{
"_id" : "76561198045636214",
"fragments" : [
{
"id" : 76561198045636215,
"source_id" : "source1"
},
{
"id" : 76561198045636216,
"source_id" : "source2"
},
{
"id" : 76561198045636217,
"source_id" : "source2"
}
]
}
내가 중복 source_ids와 조각이 포함 된 데이터베이스의 모든 레코드를 찾기 위해 노력하고 있어요 :
나는 다음과 같은 MongoDB의 구조, embeds_many
조각이 기록을 가지고있다.
저는 임베디드 문서를 쿼리 할 때 $ 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}}}}
일단 제대로 작동하면 $ 크기가 1보다 커야합니다.
이것이 가능합니까? 내가 아주 가깝다고 느낀다. 이것은 일회성 정리 작업이므로 쿼리 성능이 그리 큰 문제는 아닙니다 (업데이트 할 수있는 수백만 개의 레코드가 있습니다!)
도움이 되었습니까?
나는 원하는 결과를 얻을 수 있었지만 테스트가 너무 느리다 (우리 프로덕션 시스템을 실행하는 데는 수주가 걸릴 것이다). 문제는 레코드 당 두 번 쿼리 (우리는 프로덕션에서 ~ 3000 만 레코드가 있음)입니다.
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
와우 좋은 작품 Neil, 나는 완전히 내 자신에게있어주지 않을 것이다! 감사합니다 훌륭하게 작동;) – daveharris