CouchDB如何创建多独立键及复合键按单属性值查询
现有视图的能力边界
你当前定义的视图里,map函数是把[doc._id, doc.pos, doc.id16, doc.Oid, doc.resultTime]整个数组作为emit键。这类数组键的查询是严格遵守左前缀匹配规则的:
- 查询时必须从数组的第一个元素开始,按顺序提供匹配条件,不能跳过前面的
_id、pos、id16三个字段,直接去匹配第四位的Oid值 - 也就是说,现有这个视图完全撑不起“只按Oid查值,不管其他字段”的需求,要是强行跳过前面的前缀条件,出来的结果是混乱的,根本不准。
实现按Oid=123查询的落地方法
最直接的调整方式,就是修改map函数,给Oid这个维度单独加一个独立的查询键,不用删掉原来的组合键逻辑:
function (doc) { // 保留原来的多字段组合查询能力 emit([doc._id, doc.pos, doc.id16, doc.Oid, doc.resultTime], 1); // 单独加Oid维度的专属查询键,避免不同维度的键名冲突 if (doc.Oid !== undefined) { emit(['Oid', doc.Oid], 1); } }
等视图重新跑完索引,查询的时候直接传key=["Oid", 123],就能精准拿到所有Oid等于123的文档,完全不需要关心其他字段是什么值。
其他支持单属性查询的通用方案
- 多属性统一配置专属查询键
要是后续经常需要单字段查询pos、id16、resultTime这些值,没必要为每个字段单独建一个视图,直接在同一个map函数里把需要支持的单维度查询键都加上就行:
之后要查哪个单字段,直接传对应维度前缀的key就行,比如要查id16等于"abc"的文档,就传function (doc) { // 所有单属性查询的专属键 if (doc.pos !== undefined) emit(['pos', doc.pos], 1); if (doc.id16 !== undefined) emit(['id16', doc.id16], 1); if (doc.Oid !== undefined) emit(['Oid', doc.Oid], 1); if (doc.resultTime !== undefined) emit(['resultTime', doc.resultTime], 1); // 保留原来的组合查询能力 emit([doc._id, doc.pos, doc.id16, doc.Oid, doc.resultTime], 1); }key=["id16", "abc"]。 - 内置Mango选择器查询
这种方式不用手写map函数维护传统视图,只要给要查的字段建个简单的JSON索引,就能直接用类Mongo的选择器语法查询单字段值。比如针对Oid字段,先创建对应索引:
之后查询的时候直接传选择器条件{ "index": {"fields": ["Oid"]}, "type": "json" }{"selector": {"Oid": 123}}就能拿到结果。这种方式调整查询字段的时候不用反复改视图逻辑,灵活度高很多,适合查询需求经常变动的场景。 - 小数据集临时过滤
要是数据量特别小,只是临时调试用,可以通过all_docs接口把全量文档拉下来,在本地遍历过滤匹配目标字段的条目。但这种方式数据量大的时候传输和计算成本都很高,不适合在生产环境使用。
内容的提问来源于stack exchange,提问作者user11675534
相关产品推荐
相关产品推荐

