Javascript Firestore:按字段索引和按参数筛选
我对Firebase有一个特别的问题,就是我很难理解Firebase复合查询,也许有人比我更了解数据查询 形势 我有一个设备和位置的图形数据库,其中有一个查找表(deviceAtLocation),用于设备添加到位置的时间。使用设备ID和位置,我可以通过如下查询查找当前位置或设备:Javascript Firestore:按字段索引和按参数筛选,javascript,database,firebase,google-cloud-firestore,nosql,Javascript,Database,Firebase,Google Cloud Firestore,Nosql,我对Firebase有一个特别的问题,就是我很难理解Firebase复合查询,也许有人比我更了解数据查询 形势 我有一个设备和位置的图形数据库,其中有一个查找表(deviceAtLocation),用于设备添加到位置的时间。使用设备ID和位置,我可以通过如下查询查找当前位置或设备: Type Device { id: ID! ... } Type Location{ id: ID! ... } Type deviceAtLocation{ id: ID! timestamp: ID! dev
Type Device {
id: ID!
...
}
Type Location{
id: ID!
...
}
Type deviceAtLocation{
id: ID!
timestamp: ID!
deviceId: ID!
location: ID
...
}
const currentLocation = await db
.collection("deviceAtLocation)
.where("deviceId", "==", ARG)
.orderBy("timestamp","desc)
.limit(1)
.get()
.then((i)=>i.docs.map((d)=>d.data())[0])
这是伟大的,工作真的很好。但是问题来了,我想找出目前在一个位置的所有设备
问题
当我想查找某个位置的所有设备时,我遇到了一个问题,即必须调用整个查找表两次,首先查找当前位置的所有设备,然后查看其当前位置是否与我正在搜索的位置匹配。像这样:
const devicesAtLoc = await db
.collection("deviceAtLocation)
.where("locationId", "==", ARG)
.get()
.then((i)=>i.docs.map((d)=>d.data().deviceId)
devicesAtLoc.map(async(device)=>{
await db
.collection("deviceAtLocation)
.where("deviceId", "==", device)
.orderBy("timestamp","desc)
.limit(1)
.get()
.then((i)=>i.docs.map((d)=>d.data())[0])
}).filter((result)=>result === ARG)
我原以为这会起作用,但它仍然返回错误。我的大脑在试图思考承诺和文件时有点紧张,但仍然无法得到任何好的结果
更好的解决方案?
基本上,我正在寻找一种更好的方法来索引查找表中的所有文档,然后提取最新的文档,看看它是否位于我正在查看的位置。我不确定是否有办法按locationId编制索引,然后只查询组中最近的条目
任何帮助都将不胜感激
更新
经过大量修改后,这是两次调用查找的代码的工作版本:
async devices(par, arg) {
try {
//This needs work, I'm not sure how to get all the devices without duplicates
const devicesAtLocation = await db
.collection('deviceAtLocation')
.where('locationId', '==', par.id)
.orderBy('timestamp', 'desc')
.get()
.then((i) => i.docs.map((atLoc) => atLoc.data().deviceId));
if (!devicesAtLocation)
return new ValidationError('No device(s) found');
const filtered = await devicesAtLocation.filter(async (d) => {
const deviceAtLoc = await db
.collection('deviceAtLocation')
.where('deviceId', '==', d)
.orderBy('timestamp', 'desc')
.limit(1)
.get()
.then((i) => i.docs[0].data());
deviceAtLoc.locationId === par.id ? true : false;
});
const devices = await filtered.map(
async (d) =>
await db
.collection('mimirDevice')
.doc(d)
.get()
.then((i) => i.data())
);
return (await devices) || new ValidationError('No device(s) found');
} catch (error) {
throw new ApolloError(error);
}
},