python - mongodb 去重
怪我咯
怪我咯 2017-04-18 10:32:12
0
3
947

爬取了一个用户的论坛数据,但是这个数据库中有重复的数据,于是我想把重复的数据项给去掉。数据库的结构如下

里边的forundata是这个帖子的每个楼层的发言情况。
但是因为帖子爬取的时候有可能重复爬取了,我现在想根据里边的urlId来去掉重复的帖子,但是在去除的时候我想保留帖子的forumdata(是list类型)字段中列表长度最长的那个。
用mongodb的distinct方法只能返回重复了的帖子urlId,都不返回重复帖子的其他信息,我没法定位。。。假如重复50000个,那么我还要根据这些返回的urlId去数据库中find之后再在mongodb外边代码修改吗?可是即使这样,我发现运行的时候速度特别慢。
之后我用了group函数,但是在reduce函数中,因为我要比较forumdata函数的大小,然后决定保留哪一个forumdata,所以我要传入forumdata,但是有些forumdata大小超过了16M,导致报错,然后这样有什么解决办法吗?
或者用第三种方法,用Map_reduce,但是我在map-reduce中的reduce传入的forumdata大小限制竟然是8M,还是报错。。。

代码如下
group的代码:

reducefunc=Code(
    'function(doc,prev){'
    'if (prev==null){'
    'prev=doc'
    '}'
    'if(prev!=null){'
    'if (doc.forumdata.lenth>prev.forumdata.lenth){'
    'prev=doc'
    '}'
    '}'
    '}'
                )

map_reduce的代码:


reducefunc=Code(
    'function(urlId,forumdata){'
    'if(forumdata.lenth=1){'
    'return forumdata[0];'
    '}'
    'else if(forumdata[0].lenth>forumdata[1].lenth){'
    'return forumdata[0];'
    '}'
    'else{'
    'return forumdata[1]}'
    '}'
                )
mapfunc=Code(
    'function(){'
    'emit(this.urlId,this.forumdata)'
    '}'
)

望各位高手帮我看看这个问题该怎么解决,三个方案中随便各一个就好,或者重新帮我分析一个思路,感激不尽。
鄙人新人,问题有描述不到位的地方请提出来,我会立即补充完善。

怪我咯
怪我咯

走同样的路,发现不同的人生

membalas semua(3)
黄舟

Jika masalah ini masih belum diselesaikan, anda mungkin ingin mempertimbangkan idea berikut:

1. Pengagregatan disyorkan dalam MongoDB, tetapi pengurangan peta tidak disyorkan;

2. Antara keperluan anda, perkara yang sangat penting ialah mendapatkan panjang Forumdata: panjang tatasusunan, untuk mencari dokumen dengan panjang tatasusunan terpanjang. Artikel asal anda mengatakan bahawa Forumdata ialah satu senarai (ia mestilah tatasusunan dalam MongoDB, MongoDB menyediakan operator $size untuk mendapatkan saiz tatasusunan).

Sila rujuk buah berangan di bawah:

> db.data.aggregate([ {$project : { "_id" : 1, "name" : 1, "num" : 1, "length" : { $size : "$num"}}}])
{ "_id" : ObjectId("58e631a5f21e5d618900ec20"), "name" : "a", "num" : [ 12, 123, 22, 34, 1 ], "length" : 5 }
{ "_id" : ObjectId("58e631a5f21e5d618900ec21"), "name" : "b", "num" : [ 42, 22 ], "length" : 2 }
{ "_id" : ObjectId("58e631a7f21e5d618900ec22"), "name" : "c", "num" : [ 49 ], "length" : 1 }

3. Selepas mempunyai data di atas, anda boleh menggunakan $sort, $group, dsb. secara agregat untuk mencari objectId Dokumen yang memenuhi keperluan anda Untuk kaedah tertentu, sila rujuk siaran berikut:

https://segmentfault.com/q/10...

4. Akhirnya padamkan ObjectId yang berkaitan dalam kelompok

Serupa dengan:
var dupls = [] Simpan objectId untuk dipadamkan
db.collectionName.remove({_id:{$in:dupls}})

Untuk rujukan.

Sayangi MongoDB! Selamat Berseronok!


Cucuk saya<--Sila cucuk saya di sebelah kiri, hari ini bulan April! Pendaftaran untuk Persidangan Pengguna Shenzhen Komuniti Cina MongoDB telah bermula! Perhimpunan tuhan-tuhan yang agung!

迷茫

Jika jumlah data tidak terlalu besar, anda boleh mempertimbangkan untuk merangkak sekali lagi dan menanyakannya setiap kali anda menyimpannya Hanya set data dengan data yang paling banyak akan disimpan.
Strategi perangkak yang sangat baik>>Strategi pembersihan data yang sangat baik

PHPzhong

Terima kasih netizen Dalam kumpulan qq, seseorang memberi idea Dalam peta, forumdata diproses terlebih dahulu oleh urlId, dan urlId dan forumdatad.length diproses dalam reduce, mengekalkan forumdata.length maksimum. Satu dan urlId yang sepadan akhirnya disimpan ke dalam pangkalan data, dan kemudian semua data dibaca daripada pangkalan data asal melalui urlId dalam pangkalan data ini. Saya mencubanya walaupun kecekapannya tidak seperti yang saya jangkakan, kelajuannya masih jauh lebih pantas daripada menggunakan python sebelum ini.
Lampirkan peta dan kurangkan kod:
'''javaScript
mapfunc=Code(

'function(){'
'data=new Array();'
'data={lenth:this.forumdata.length,'
'id:this._id};'
# 'data=this._id;'
'emit({"id":this.urlId},data);'
'}'
)

reducefunc=Kod(

'function(tieziID,dataset){'
'reduceid=null;'
'reducelenth=0;'
''
''
'redecenum1=0;'
'redecenum2=0;'
''
'dataset.forEach(function(val){'
'if(reducelenth<=val["lenth"]){'
'reducelenth=val["lenth"];'
'reduceid=val["id"];'
'redecenum1+=1;'
'}'
'redecenum2+=1;'
'});'
'return {"lenth":reducelenth,"id":reduceid};'
'}'
            )
上边是先导出一个新的数据库的代码,下边是处理这个数据库的代码:

mapfunc=Kod(

'function(){'
# 'data=new Array();'
'lenth=this.forumdata.length;'
''
'emit(this.urlId,lenth);'
'}'

)

reducefunc=Kod(

'function(key,value){'
'return value;'
'}'

)

之后添加到相应的map_reduce中就行了。
感觉Bgou回答的不错,所以就选他的答案了,还没有去实践。上边是我的做法,就当以后给遇到同样问题的人有一个参考。
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!