如何针对含厂商与产品条件的Firestore嵌套数组高效查询?
Firestore嵌套数组的厂商/产品条件查询问题
我有一个包含嵌套数组的Firestore数据结构,现在需要基于嵌套数组里的**厂商(vendor)和产品(product)**条件高效查询文档,但找不到合适的方法。
简化后的数据结构
"configurations": { "CVE_data_version": "4.0", "nodes": [ { "operator": "OR", "children": [], "cpe_match": [ { "vulnerable": true, "vendor": "redhat", "product": "enterprise_linux:", "cpe23Uri": "cpe:2.3:o:redhat:enterprise_linux:8.0:*:*:*:*:*:*:*", "cpe_name": [] } ] }, // 其他节点 ] }
我的查询尝试
const cveQuery = query( cveCollectionRef, where('configurations.nodes', 'array-contains', { 'cpe_match': { 'vendor': 'redhat', 'product': 'enterprise_linux' } }) );
请问有没有基于厂商和产品条件的嵌套查询方式?
解决方案
Firestore的array-contains要求匹配完整的数组元素,你当前的写法无法生效——它会尝试匹配整个nodes元素(包括operator、children等字段),而非仅cpe_match里的vendor和product。以下是几种可行方案:
1. 嵌套字段直接查询(单层嵌套适用)
通过点路径直接定位到cpe_match内的字段,Firestore会自动匹配数组中任意符合条件的项:
const cveQuery = query( cveCollectionRef, where('configurations.nodes.cpe_match.vendor', '==', 'redhat'), where('configurations.nodes.cpe_match.product', '==', 'enterprise_linux') );
该查询会返回所有包含至少一组符合vendor和product条件的cpe_match项的文档。
2. 重构数据结构(推荐,性能最优)
多层嵌套数组的查询在Firestore中天生受限,若需频繁按vendor和product查询,建议将查询字段扁平化,比如新增顶层数组字段cpe_entries:
"cpe_entries": [ {"vendor": "redhat", "product": "enterprise_linux"}, // 其他所有cpe_match的vendor和product组合 ]
之后可直接用array-contains或灵活的字段查询:
// 匹配特定厂商+产品组合 const cveQuery = query( cveCollectionRef, where('cpe_entries', 'array-contains', { vendor: 'redhat', product: 'enterprise_linux' }) ); // 仅按厂商查询(可新增顶层数组"vendors"存储所有厂商值) const vendorQuery = query( cveCollectionRef, where('vendors', 'array-contains', 'redhat') );
这种方式能让Firestore直接对顶层字段建立索引,查询效率最高。
3. 内存筛选(无法改结构时的备选)
若不能修改现有数据结构,可先获取文档集,再在内存中筛选符合条件的项:
const snapshot = await getDocs(cveCollectionRef); const matchedDocs = []; snapshot.forEach(doc => { const data = doc.data(); // 遍历嵌套数组检查匹配项 const hasMatch = data.configurations.nodes.some(node => node.cpe_match.some(cpe => cpe.vendor === 'redhat' && cpe.product === 'enterprise_linux' ) ); if (hasMatch) { matchedDocs.push(doc); } });
注意:该方法仅适合数据量较小的场景,否则会产生性能和成本问题。
内容的提问来源于stack exchange,提问作者cryxnet
相关产品推荐
相关产品推荐

