使用事务检查是否存在多个文档,如果不存在则添加它们

时间:2018-02-07 20:00:35

标签: javascript firebase transactions google-cloud-firestore

这是我的情况:我有一个包含大量条目的本地json文件。此文件未经过清理(即列表中可能存在重复的条目)。我的目标是使用firestore将每个项目(一次)从本地文件添加到我的数据库。

文档说,一个事务可以是多个get操作,然后是多个update/set/delete操作。但是,这些示例通常只有一个get。如何在then()内嵌套而不进行多次获取操作?我想我可以得到整个系列并比较结果。但后来我不会学会如何使用多个get

示例数据:

/* mock data */
var myList = [
    {
        id: '123',
        name: 'Aloha 1',
        latitude: 0.0,
        longitude: 1.1,
        url: 'https://www.google.com'
    },
    {
        id: '321',
        name: 'Aloha 2',
        latitude: 3.0,
        longitude: 3.1,
        url: 'https://www.gmail.com'
    },
    {
        id: '123',
        name: 'Aloha 1',
        latitude: 0.0,
        longitude: 1.1,
        url: 'https://www.google.com'
    },
    {
        id: '321',
        name: 'Aloha 2',
        latitude: 3.0,
        longitude: 3.1,
        url: 'https://www.gmail.com'
    }
];

这是我的尝试(我知道这是错误的,我有一系列get / set操作......):

var transaction = db.runTransaction(t => {
    for (item in myList) {
        const ref = db.collection('superList').doc(item.id);
        const sanitizedEntry = {
            name: item.name,
            location: new admin.firestore.GeoPoint(item.lat, item.lon),
            url: item.url,
        }
        t.get(ref).then(doc => {
            if (!doc.exists) {
                t.set(ref, sanitizedEntry);
            }
        });
    }
})
.then(result => {
    console.log('Transaction success!');
})
.catch(err => {
    console.log('Transaction failure:', err);
});

生成的数据库应该只包含superList/123superList/321(以及集合中已有的其他文档)。

2 个答案:

答案 0 :(得分:0)

根据建议,不使用交易工作正常(编辑:固定代码):

for (item in myList) {
     const itemRef = db.collection('superList').doc(item.id);
     const itemDoc = itemRef.get()
                .then(itemSnap => {
                    if (!itemSnap.exists) {
                        const itemObj = {
                            name: gymitemRaw.name,
                            location: new admin.firestore.GeoPoint(item.llatitude, item.longitude),
                            url: item.url,
                        };
                        itemRef.set(itemObj);
                    }else{
                        console.log('Item already exists in DB');
                    }
                });
}

答案 1 :(得分:0)

如果要检查固定数量的项目,可以使用getAll同时获取许多文档。这是一个全有或全无的结果。您将获得所有文件或错误。

let superList = db.collection('superList');
let myRef0 = superList.doc(item[0].id);
let myRef1 = superList.doc(item[1].id);
let myRef2 = superList.doc(item[2].id);
let myRef3 = superList.doc(item[3].id);

return db.getAll(itemRef0, itemRef1, itemRef2, itemRef3).then(response => {
  // The data is returned in an array, here
}.catch(err => {
  console.error(`An error happened ${err}`);
});