一个查询中的 Firestore 查询时间戳和 geohash
Firestore query timestamp and geohash in one query
我正在尝试使用时间戳和 geohash 查询我的 Firestore 数据库,但返回的结果总是空数组。如果我只使用 geohash 或只使用时间戳,那么我会得到结果,但是当我一起使用它们时没有结果。当 运行 此查询时,我在控制台中也没有收到任何错误。我不确定为什么这个查询不起作用,任何帮助将不胜感激。另外值得注意的是,我正在使用 Firebase 文档中建议的方法来处理 geohash 查询。这是查询代码:
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
const query = firebase
.firestore()
.collection('scheduledWorkouts')
.where('date', '>=', start) // start is a Firebase timestamp variable
.where('date', '<=', end) // end is a Firebase timestamp variable
.orderBy('date')
.orderBy('geohash')
.startAt(b[0])
.endAt(b[1]);
promises.push(query.get());
}
Promise.all(promises)
.then((snapshots) => {
const matchingDocs = [];
for (const snap of snapshots) {
for (const doc of snap.docs) {
const lat = doc.get('location.lat');
const lng = doc.get('location.lng');
// filtering out false positives
const distanceInKm = geofire.distanceBetween(
[lat, lng],
center
);
const distanceInM = distanceInKm * 1000;
if (distanceInM <= radiusInM) {
matchingDocs.push(doc.data());
}
}
}
return matchingDocs;
})
.then((matchingDocs) => {
console.log(matchingDocs);
})
.catch((error) => {
console.log(error);
});
Firestore 对查询有此限制:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.
虽然没有明确提到,start*
和 end*
过滤器也受此限制。
通过使用 geohash,您已经通过将纬度和经度组合成一个可以排序和过滤的值来解决这个限制。但是通过在 date
上添加范围过滤器,您又遇到了同样的限制。
根据纬度、经度和日期筛选的唯一方法:
- 通过以允许的格式存储日期,对日期使用相等过滤器。例如,如果您想允许过滤特定的一周,您可以将日期存储为
2021-05-26
格式,并对 7 个值执行 in
查询。
- 找到一种方法将时间戳与您自己的值类型中的纬度和经度结合起来,类似于 geohash 已经为纬度和经度所做的事情。这意味着您必须有效地表达时间与距离的关系,因此通常只在定义明确的领域中才可行。
我正在尝试使用时间戳和 geohash 查询我的 Firestore 数据库,但返回的结果总是空数组。如果我只使用 geohash 或只使用时间戳,那么我会得到结果,但是当我一起使用它们时没有结果。当 运行 此查询时,我在控制台中也没有收到任何错误。我不确定为什么这个查询不起作用,任何帮助将不胜感激。另外值得注意的是,我正在使用 Firebase 文档中建议的方法来处理 geohash 查询。这是查询代码:
const bounds = geofire.geohashQueryBounds(center, radiusInM);
const promises = [];
for (const b of bounds) {
const query = firebase
.firestore()
.collection('scheduledWorkouts')
.where('date', '>=', start) // start is a Firebase timestamp variable
.where('date', '<=', end) // end is a Firebase timestamp variable
.orderBy('date')
.orderBy('geohash')
.startAt(b[0])
.endAt(b[1]);
promises.push(query.get());
}
Promise.all(promises)
.then((snapshots) => {
const matchingDocs = [];
for (const snap of snapshots) {
for (const doc of snap.docs) {
const lat = doc.get('location.lat');
const lng = doc.get('location.lng');
// filtering out false positives
const distanceInKm = geofire.distanceBetween(
[lat, lng],
center
);
const distanceInM = distanceInKm * 1000;
if (distanceInM <= radiusInM) {
matchingDocs.push(doc.data());
}
}
}
return matchingDocs;
})
.then((matchingDocs) => {
console.log(matchingDocs);
})
.catch((error) => {
console.log(error);
});
Firestore 对查询有此限制:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.
虽然没有明确提到,start*
和 end*
过滤器也受此限制。
通过使用 geohash,您已经通过将纬度和经度组合成一个可以排序和过滤的值来解决这个限制。但是通过在 date
上添加范围过滤器,您又遇到了同样的限制。
根据纬度、经度和日期筛选的唯一方法:
- 通过以允许的格式存储日期,对日期使用相等过滤器。例如,如果您想允许过滤特定的一周,您可以将日期存储为
2021-05-26
格式,并对 7 个值执行in
查询。 - 找到一种方法将时间戳与您自己的值类型中的纬度和经度结合起来,类似于 geohash 已经为纬度和经度所做的事情。这意味着您必须有效地表达时间与距离的关系,因此通常只在定义明确的领域中才可行。