使用主键从 BaseX 中删除重复实体
delete duplicate entities from BaseX with a primary key
如何删除重复条目?
在这种情况下,Twitter 使用雪花作为推文 JSON
中的唯一 ID 字段,如下所示。按 ID 构建 index 条推文,然后删除每一条重复的 $tweet
条推文?但是如何不以递归方式删除每一条推文...?
A simple FLWOR
打印数据库中每条推文的 ID:
for $tweets in db:open("twitter")
return <tweet>{$tweets/json/id__str}</tweet>
结果:
thufir@dur:~/flwor/twitter$
thufir@dur:~/flwor/twitter$ basex tweetID.xq
<tweet>
<id__str>1224165280068382720</id__str>
</tweet>
<tweet>
<id__str>1224160851797643264</id__str>
</tweet>
<tweet>
<id__str>1224134565280862208</id__str>
</tweet>
...
<tweet>
<id__str>1224016596634603520</id__str>
</tweet>
<tweet>
<id__str>1224001430417297410</id__str>
</tweet>
<tweet>
<id__str>1223987662094249991</id__str>
</tweet>thufir@dur:~/flwor/twitter$
thufir@dur:~/flwor/twitter$
这里的重复是有意的,但正在寻找某种方式 "clean up" 数据库。
只是在寻找一个大纲或方法。我的想法是将一个 xquery
的输出通过管道传输到另一个 xquery
,但我对如何构建索引感到困惑。大概这是一个functionality built into the database itself, just need to leverage the correct module (probably).
--
这看起来 return 一个 different 结果,至少:
distinct-values(
for $tweets in db:open("twitter")
return ($tweets/json/id__str))
尽管我不太确定它是所有 id__str
值的集合。
您可以在 FLOWER 中使用 group by 来获取重复项。它也应该比 distinct()
.
快
for $tweets in db:open("twitter")
let $id := $tweets/json/id__str
group by $id
return
if (count($tweets) > 1)
then (for-each(tail($tweets), function ($tweet) { (: remove $tweet from DB :) } )
else () (: nothing to do :)
我遇到了同样的问题并测试了这里已经讨论过的两种方法。这两种方法都可用于删除重复项,但存在性能差异。
distinct-values
方法:
(: Open database :)
let $db := db:open('db-name')
(: Get all distinct IDs :)
let $ids := distinct-values($db/record/id)
for $id in $ids
(: Get all records with the same ID :)
let $recsWithSameId := data($db/record/id)=$id
(: Return only duplicate records :)
return if (count($recsWithSameId)>1) then
$recsWithSameId
(: Instead of returning the duplicate records you can now delete all records except the one you want to keep. Then you removed the duplicates. :)
group by
方法:
for $recs in db:open('db-name')/record
let $id := $recs/id
group by $id
return
if (count($recs) > 1) then
$recs
(: Instead of returning the duplicate records you can now delete all records except the one you want to keep. Then you removed the duplicates. :)
第二种方法 (group by
) 比第一种 (distinct-values
) 快得多。
如何删除重复条目?
在这种情况下,Twitter 使用雪花作为推文 JSON
中的唯一 ID 字段,如下所示。按 ID 构建 index 条推文,然后删除每一条重复的 $tweet
条推文?但是如何不以递归方式删除每一条推文...?
A simple FLWOR
打印数据库中每条推文的 ID:
for $tweets in db:open("twitter")
return <tweet>{$tweets/json/id__str}</tweet>
结果:
thufir@dur:~/flwor/twitter$
thufir@dur:~/flwor/twitter$ basex tweetID.xq
<tweet>
<id__str>1224165280068382720</id__str>
</tweet>
<tweet>
<id__str>1224160851797643264</id__str>
</tweet>
<tweet>
<id__str>1224134565280862208</id__str>
</tweet>
...
<tweet>
<id__str>1224016596634603520</id__str>
</tweet>
<tweet>
<id__str>1224001430417297410</id__str>
</tweet>
<tweet>
<id__str>1223987662094249991</id__str>
</tweet>thufir@dur:~/flwor/twitter$
thufir@dur:~/flwor/twitter$
这里的重复是有意的,但正在寻找某种方式 "clean up" 数据库。
只是在寻找一个大纲或方法。我的想法是将一个 xquery
的输出通过管道传输到另一个 xquery
,但我对如何构建索引感到困惑。大概这是一个functionality built into the database itself, just need to leverage the correct module (probably).
--
这看起来 return 一个 different 结果,至少:
distinct-values(
for $tweets in db:open("twitter")
return ($tweets/json/id__str))
尽管我不太确定它是所有 id__str
值的集合。
您可以在 FLOWER 中使用 group by 来获取重复项。它也应该比 distinct()
.
for $tweets in db:open("twitter")
let $id := $tweets/json/id__str
group by $id
return
if (count($tweets) > 1)
then (for-each(tail($tweets), function ($tweet) { (: remove $tweet from DB :) } )
else () (: nothing to do :)
我遇到了同样的问题并测试了这里已经讨论过的两种方法。这两种方法都可用于删除重复项,但存在性能差异。
distinct-values
方法:(: Open database :) let $db := db:open('db-name') (: Get all distinct IDs :) let $ids := distinct-values($db/record/id) for $id in $ids (: Get all records with the same ID :) let $recsWithSameId := data($db/record/id)=$id (: Return only duplicate records :) return if (count($recsWithSameId)>1) then $recsWithSameId (: Instead of returning the duplicate records you can now delete all records except the one you want to keep. Then you removed the duplicates. :)
group by
方法:for $recs in db:open('db-name')/record let $id := $recs/id group by $id return if (count($recs) > 1) then $recs (: Instead of returning the duplicate records you can now delete all records except the one you want to keep. Then you removed the duplicates. :)
第二种方法 (group by
) 比第一种 (distinct-values
) 快得多。