我的情况如下:
我正在使用BING新闻api,并且从api返回的是以下对象的列表:
{
"name": "Eterna Resenha contará com as participações de Neto e Vampeta",
"url": "https://www.terra.com.br/esportes/lance/eterna-resenha-contara-com-as-participacoes-de-neto-e-vampeta,82e493e511734febfcdfda6fbd22c105xjafr9k2.html",
"image": {
"contentUrl": "http://p2.trrsf.com/image/fget/cf/800/450/middle/images.terra.com/2020/05/27/5ece8e302d1fb.jpeg",
"thumbnail": {
"contentUrl": "https://www.bing.com/th?id=ON.4E1CF6986982B70A3D6009F435822EF2&pid=News",
"width": 700,
"height": 393
}
},
"description": "Durante a quarentena, as lives tomaram conta do país, tentando arrecadar doações para ajudar quem sofre com o coronavírus...",
"provider": [
{
"_type": "Organization",
"name": "Terra"
}
],
"datePublished": "2020-05-28T00:00:00.0000000Z",
"category": "Entertainment"
}
请注意,此对象中没有id
字段,因此我通过将datePublished
字段更改为Date
并使用getTime
方法返回一个long值,然后将其与新闻连接,即兴创建了一个id语言如下:
const time = new Date(news.datePublished).getTime()
const id = `${language}${time}`
await database.collection(`news`).doc(`${id}`).set(news, { merge: true })
当从BING api返回相同的新闻并更新日期,导致该对象在我的Firestore数据库中重复时,此解决方案变得效率低下。
我打算使用的解决方案
使用如下hash
算法将新闻网址转换为sha1
:
const CryptoJS = require("crypto-js");
const id = `${CryptoJS.SHA1(news.url)}`
await database.collection(`news`).doc(`${id}`).set(news, { merge: true })
firestore document creation best practices指南保留了使用这种格式的ID的范围。但是我主要关心的是具有大id(d40e5b8df6462e138fe617a84ddabae7f78360a6)的广告,因为我将使用至少5种语言发布成千上万的新闻。
我想知道是否有让我选择其他解决方案的对策?
您可以使用Firestore的默认ID生成器功能。我很确定“大ID”不会引起明显的性能问题,因此Google为什么要使用这种功能在其数据库中生成唯一ID。
这是我提取并在我的项目中使用了很长时间的功能:
const generateId = function () {
// Alphanumeric characters
const chars =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let autoId = '';
for (let i = 0; i < 20; i++) {
autoId += chars.charAt(Math.floor(Math.random() * chars.length));
}
return autoId;
};
使用此功能几乎不可能出现两个文档使用相同ID的可能性,但是您可以继续进行操作,并在结果中添加时间戳,以简化您的操作。