我一直在努力寻找这个要求的解决方案,但我遇到了许多死胡同。
我正在使用 Cloudant 作为用户文档的数据存储。每个用户文档都有一个名为“items”的字段(属性),它是一个对象数组。
因此用户文档如下所示:
{
"_id":"userid1",
"_rev":"XX",
"username": "foobaruser"
"items":
[
{
"date":1357879144069,
"text":"don't cry because it's over, smile because it happened.",
"cat":"determination"
},
{
"date":1357879179209,
"text":"those who mind don't matter, and those who matter don't mind.",
"cat":"fitness"
},
{
"date":1357883809736,
"text":"be the change that you wish to see in the world.",
"cat":"determination"
},
{
"date":1357879179209,
"text":"those who mind don't matter, and those who matter don't mind.",
"cat":"hardwork"
},
{
"date":1357879179209,
"text":"those who mind don't matter, and those who matter don't mind.",
"cat":"determination"
}
]
}
要求:
理想情况下,我想在视图上使用搜索功能并传入“cat”的值,然后返回所有与“cat”值匹配的文档中的所有“项目”。
e.g。 HTTPS:// [用户名] .cloudant.com / DBNAME / _design /视图/ _search / DOC Q =判定
上述搜索将返回所有用户文档中“items”中的所有对象,其中“cat = determination”的格式与此类似:
{
"total_rows": 2,
"rows":
[{
"id": "userid1",
"items":
[
{
"date":1357879144069,
"text":"don't cry because it's over, smile because it happened.",
"cat":"determination"
},
{
"date":1357883809736,
"text":"be the change that you wish to see in the world.",
"cat":"determination"
},
{
"date":1357879179209,
"text":"those who mind don't matter, and those who matter don't mind.",
"cat":"determination"
}
]
},
{
"id": "userid2",
"items":
[
{
"date":135787966655,
"text":"Some text",
"cat":"determination"
}
]
}]
}
如果使用“搜索”无法做到这一点,那么是否可以使用二级索引来实现这一目标?
答案 0 :(得分:5)
在CouchDB中,您无法将查询参数的动态值传递给视图(在您的情况下为cat = determination)。 CouchDB中的方法是创建一个更通用的视图,然后在调用视图以获取所需数据时调整结果的排序方式。
您需要在db的设计文档中创建自定义视图才能实现此目的:
byUserItemCat: {
map: function (doc) {
if ( !doc.items || doc.items.length === 0 ) return;
for ( var i=0; i<doc.items.length; i++ ) {
emit(doc.items[i].cat,{doc._id,doc.items[i].date,doc.items[i].text});
}
}
}
因此,上面的视图将获取db中的每个doc,检查它是否包含带有内容的items数组,然后遍历所有doc的项目。对于每个item元素,它会将cat
作为索引发送到结果集中,这很重要,因为我们可以针对此索引进行排序。我们可以自由地构建结果对象(emit
的第二个参数),在上面的例子中,我构建了一个具有用户ID的对象,以及项目&#39;日期和文字。
您可以调用此类视图来获取所有结果:
curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat
如果您只对索引键(即cat
)的结果感兴趣,那么&#34;确定&#34;你做了:
curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat?key="determination"
答案 1 :(得分:1)
Cloudant的搜索以返回文档的粒度进行。您的索引功能可以对文档中item
的所用类别编制索引,然后您的搜索将返回包含您提及的类别的item
的文档。然后,您的应用程序代码需要过滤到item
以返回客户端。
你的索引功能就像(从Wintamute无耻地抄袭):
if (!doc.items || doc.items.length === 0) return;
var item;
for (var i=0; i<doc.items.length; i++) {
index("cat", doc.items[i].cat, {"index": "not_analyzed"});
}
另一种方法是,如果您真的希望能够获得物品,可以将物品分解成自己的文件。
然而,我是第二个(并且已经投票)Wintamute的回答,因为我同意建议的视图是这个特定情况下的最佳解决方案(通过cat
查找和显示项目)。
答案 2 :(得分:1)
这实际上可以通过Cloudant搜索来完成。我有一个类似的问题,我需要解决。特别感谢Cloudant的Mike Bresslin的帮助。
function(doc){
if (doc.items) {
for (var n in doc.items) {
if (doc.items[n].cat) {
index("cat", doc.items[n].cat, { store : true });
}
}
}
}
您可以在搜索中将其查询为:
?q=cat:hardwork OR cat:determination