如何在不修改限制的情况下进行分页?
How can i do the pagination without modifying the limit?
如何获得用户要求的相同元素?
例如,如果我这样做,用户要求 30
query = query.limit(30)
const qSnap = await query.get(); // 30 objects
qSnap.docs.forEach((doc) => { // i will get fewer than 30
const item = doc.data().data.tools.find(t => t.trait === 'color1' && t.value == 'red');
console.log(item)
})
我需要过滤,因为我有这个结构:
{
name:carla
data: "{
sign: "carly",
tools: [{trait:color1, value:red}, {trait:color2, value:white}] }"
},{
name:dany
data: "{
sign: "dan",
tools: "[{trait:color1, value:blue}, {trait:color2, value:black}]
}"
}
或者我怎样才能增强我的结构来避免这个问题?
你需要先过滤数据,他们限制了。使用这个语法。
const toolsFilter = {
trait: 'color1',
value:'red'
}
const qSnap = await query.where('tools','array-contains',toolsFilter)
.limit(30)
.get();
qSnap.docs.forEach((doc) => {
const item = doc.data().data;
console.log(item)
}))
有关查询语法等的更多信息,请参阅 Firebase 在线文档。https://firebase.google.com/docs/firestore/query-data/queries
这也解释了使用查询游标进行分页https://firebase.google.com/docs/firestore/query-data/query-cursors
采用斯图尔特的回答并稍作修改(抱歉,我无法在评论中这样做)
const toolsFilter = {
trait: 'color1',
value:'red'
}
const qSnap = await query.where('tools','array-contains-any', toolsFilter)
.limit(30)
.get();
qSnap.docs.forEach((doc) => {
const item = doc.data().data;
console.log(item)
}))
array-contains
操作检查数组是否包含特定(完整)值。它无法检查对象数组是否包含具有 属性 特定值的项目。唯一的办法就是查询数组里面的整个对象。
在此示例结构中:
data: {
sign: "carly",
tools: [{trait:color1, value:red}, {trait:color2, value:white}] }
}
您想查询数组映射内的对象。请参阅下面的 Firestore 屏幕截图以获得更好的可视化效果:
为了能够查询数组映射内的对象,您必须查询其中的整个对象。请参阅下面的示例查询:
// As you can see here, you need to be able to jump inside the `data.tools`
// Then query the `tools` array by using objects.
const toolsRef = db.collection("someCollection").where("data.tools", "array-contains", {trait: "color1", value: "red"})
完整代码供参考:
const toolsRef = db.collection("someCollection").where("data.tools", "array-contains", {trait: "color1", value: "red"})
query = toolsRef.limit(30)
query.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// Do anything with the result.
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
结果应该是这样的:
5nwzwpxr7BmctvznEypl => {
name: 'carla',
data: { tools: [ [Object], [Object] ], sign: 'carly' }
}
有关详细信息,请参阅 Array Memberships。
更新:
Firestore 无法从文档字段中搜索其中编码了 JSON 对象的方法。您应该首先解析 JSON 对象以 get/filter 必要的数据。例如:
query = query.limit(30);
const qSnap = await query.get();
qSnap.docs.forEach((doc) => {
const data = JSON.parse(doc.data().data);
const items = data.tools.filter(t => t.trait === "color1" && t.value === "red");
console.log(items);
})
但是,上面与您的类似的代码段可能会导致问题,该问题与您在查询中设置的 limit()
不同。为了增强您的结构,我建议将其放在文档字段中,就像我在上面的原始答案中给出的那样。
document
(fields)
|- name(string): "carla"
|- data(map)
|- sign(string): "carly"
|- tools(array)
|- (map)
| - trait(string): "color1"
| - value(string): "red"
|- (map)
- trait(string): "color2"
- value(string): "white"
此结构与 data
字段中编码的 JSON 对象相同。使用此结构的优点是您现在可以使用我在原始 post 上向您展示的 Firestore 进行查询。如果不使用客户端过滤,这将导致 30 个文档。如果查询找不到匹配的文档,它只会少于 30。
为此,您只需构建 JSON 对象并将数据设置到文档中。参见例如下面:
db.collection("someCollection").add({
data: {
sign: "carly",
tools: [{trait: "color1", value:"red"}, {trait:"color2", value:"white"}]
},
name: "carla"
})
.then((docRef) => {
console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
console.error("Error adding document: ", error);
});
如何获得用户要求的相同元素?
例如,如果我这样做,用户要求 30
query = query.limit(30)
const qSnap = await query.get(); // 30 objects
qSnap.docs.forEach((doc) => { // i will get fewer than 30
const item = doc.data().data.tools.find(t => t.trait === 'color1' && t.value == 'red');
console.log(item)
})
我需要过滤,因为我有这个结构:
{
name:carla
data: "{
sign: "carly",
tools: [{trait:color1, value:red}, {trait:color2, value:white}] }"
},{
name:dany
data: "{
sign: "dan",
tools: "[{trait:color1, value:blue}, {trait:color2, value:black}]
}"
}
或者我怎样才能增强我的结构来避免这个问题?
你需要先过滤数据,他们限制了。使用这个语法。
const toolsFilter = {
trait: 'color1',
value:'red'
}
const qSnap = await query.where('tools','array-contains',toolsFilter)
.limit(30)
.get();
qSnap.docs.forEach((doc) => {
const item = doc.data().data;
console.log(item)
}))
有关查询语法等的更多信息,请参阅 Firebase 在线文档。https://firebase.google.com/docs/firestore/query-data/queries
这也解释了使用查询游标进行分页https://firebase.google.com/docs/firestore/query-data/query-cursors
采用斯图尔特的回答并稍作修改(抱歉,我无法在评论中这样做)
const toolsFilter = {
trait: 'color1',
value:'red'
}
const qSnap = await query.where('tools','array-contains-any', toolsFilter)
.limit(30)
.get();
qSnap.docs.forEach((doc) => {
const item = doc.data().data;
console.log(item)
}))
array-contains
操作检查数组是否包含特定(完整)值。它无法检查对象数组是否包含具有 属性 特定值的项目。唯一的办法就是查询数组里面的整个对象。
在此示例结构中:
data: {
sign: "carly",
tools: [{trait:color1, value:red}, {trait:color2, value:white}] }
}
您想查询数组映射内的对象。请参阅下面的 Firestore 屏幕截图以获得更好的可视化效果:
为了能够查询数组映射内的对象,您必须查询其中的整个对象。请参阅下面的示例查询:
// As you can see here, you need to be able to jump inside the `data.tools`
// Then query the `tools` array by using objects.
const toolsRef = db.collection("someCollection").where("data.tools", "array-contains", {trait: "color1", value: "red"})
完整代码供参考:
const toolsRef = db.collection("someCollection").where("data.tools", "array-contains", {trait: "color1", value: "red"})
query = toolsRef.limit(30)
query.get()
.then((querySnapshot) => {
querySnapshot.forEach((doc) => {
// Do anything with the result.
console.log(doc.id, " => ", doc.data());
});
})
.catch((error) => {
console.log("Error getting documents: ", error);
});
结果应该是这样的:
5nwzwpxr7BmctvznEypl => {
name: 'carla',
data: { tools: [ [Object], [Object] ], sign: 'carly' }
}
有关详细信息,请参阅 Array Memberships。
更新:
Firestore 无法从文档字段中搜索其中编码了 JSON 对象的方法。您应该首先解析 JSON 对象以 get/filter 必要的数据。例如:
query = query.limit(30);
const qSnap = await query.get();
qSnap.docs.forEach((doc) => {
const data = JSON.parse(doc.data().data);
const items = data.tools.filter(t => t.trait === "color1" && t.value === "red");
console.log(items);
})
但是,上面与您的类似的代码段可能会导致问题,该问题与您在查询中设置的 limit()
不同。为了增强您的结构,我建议将其放在文档字段中,就像我在上面的原始答案中给出的那样。
document
(fields)
|- name(string): "carla"
|- data(map)
|- sign(string): "carly"
|- tools(array)
|- (map)
| - trait(string): "color1"
| - value(string): "red"
|- (map)
- trait(string): "color2"
- value(string): "white"
此结构与 data
字段中编码的 JSON 对象相同。使用此结构的优点是您现在可以使用我在原始 post 上向您展示的 Firestore 进行查询。如果不使用客户端过滤,这将导致 30 个文档。如果查询找不到匹配的文档,它只会少于 30。
为此,您只需构建 JSON 对象并将数据设置到文档中。参见例如下面:
db.collection("someCollection").add({
data: {
sign: "carly",
tools: [{trait: "color1", value:"red"}, {trait:"color2", value:"white"}]
},
name: "carla"
})
.then((docRef) => {
console.log("Document written with ID: ", docRef.id);
})
.catch((error) => {
console.error("Error adding document: ", error);
});