如何解决CouchDB Mango 查询 - 将任意键与数组项匹配
{
"_id": "doc1"
"binds": {
"subject": {
"Test1": ["something"]
},"object": {
"Test2": ["something"]
}
},},{
"_id": "doc2"
"binds": {
"subject": {
"Test1": ["something"]
},"object": {
"Test3": ["something"]
}
},}
我需要一个 Mango 选择器来检索文档,其中绑定内的任何字段(主题、对象等)都有一个对象,其键等于作为参数传递的数组中的任何值。也就是说,if keys of binds contains any values of some array it should returns that document
。
例如,考虑数组 ["Test2"]
我的选择器应该检索 doc1
,因为 binds["subject"]["Test1"]
存在;数组 ["Test1"]
应该检索 doc1
和 doc2
,数组 ["Test2","Test3"]
还应该检索 doc1
和 doc2
。
F.Y.I.我使用带有 nano 库的 Node.js 来访问 CouchDB API。
解决方法
我提供这个答案是因为改变文档“架构”并不总是一种选择。
对于给定的文档结构,Mango 无法以任何合理的方式做到这一点。是的,它可以做到,但前提是采用非常脆弱和低效的做法。
Mango 没有提供一种有效的方式来查询文档的动态属性;它确实支持在属性值中搜索,例如数组1.
使用最坏的做法,此选择器将查找具有绑定属性 subject
和 object
的文档,这些文档具有名为 Test2
和 Test3
的属性
{
"selector": {
"$or": [
{
"binds.subject.Test2": {
"$exists": true
}
},{
"binds.object.Test2": {
"$exists": true
}
},{
"binds.subject.Test3": {
"$exists": true
}
},{
"binds.object.Test3": {
"$exists": true
}
}
]
}
}
Yuk。
问题
- 查询的属性名称各不相同,因此无法利用 Mango 索引(Test37 是否有人?)
- 因为 (1) 全索引扫描 (
_all_docs
) 每次查询都会发生 - 需要以编程方式生成
$or
子句 - 需要了解要查询的属性名称集(Test37 是否有人?)
给定的文档结构是 Mango 索引和查询的一个展示器。
这就是 map/reduce 的亮点
考虑带有 map 函数的 view
function (doc) {
for(var prop in doc.binds) {
if(doc.binds.hasOwnProperty(prop)) {
// prop = subject,object,foo,bar,etc
var obj = doc.binds[prop];
for(var objProp in obj) {
if(obj.hasOwnProperty(objProp)) {
// objProp = Test1,Test2,Test37,Fubar,etc
emit(objProp,prop)
}
}
}
}
}
因此,map 函数为具有 binds
属性和两个嵌套属性的任何文档创建视图,例如binds.subject.Test1
、binds.foo.bar
。
鉴于问题中的两个文档,这将是基本视图索引
id | key | value |
---|---|---|
doc1 | Test1 | 主题 |
doc2 | Test1 | 主题 |
doc1 | Test2 | 对象 |
doc2 | Test3 | 对象 |
并且由于视图查询提供 keys
参数,因此此查询将使用 JSON 提供您的特定解决方案
{
include_docs: true,reduce: false,keys: ["Test2","Test3"]
}
使用 cUrl 查询该索引
$ curl -G http://{查看端点} -d 'include_docs=false' -d 'reduce=false' -d 'keys=["Test2","Test3"]'
会回来
{
"total_rows": 4,"offset": 2,"rows": [
{
"id": "doc1","key": "Test2","value": "object"
},{
"id": "doc2","key": "Test3","value": "object"
}
]
}
当然可以选择利用 collation and complex keys 来扩展这种视图的形式和功能,还有方便的 reduce 功能。
我看到评论说 Mango 非常适合 CouchDB 的新手,因为它在创建索引和查询选项方面“很容易”,如果经验丰富,则可以使用 map/reduce。我相信这些评论是善意的,但被误导了;芒果很诱人,但也有它的缺陷1。视图确实需要深思熟虑,但嘿,无论如何,这都是我们应该做的。
1)$elemMatch
例如需要内存扫描,这可能非常昂贵。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。