4

我一直在尝试为这个要求找到解决方案,但我遇到了很多死胡同。

我使用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"
      }
   ]
}
  • 数据存储中有多个这样的用户文档,每个文档都有属性“项目”

要求:

  1. 理想情况下,我想在视图上使用搜索功能并传入“cat”的值,然后返回所有文档中与“cat”值匹配的所有“项目”。

    例如 https://[用户名].cloudant.com/dbname/_design/views/_search/doc?q=determination

  2. 上面的搜索将返回所有用户文档中“项目”中的所有对象,这些文档具有“cat = 确定”,格式类似于:

    {
        "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"
                }
            ]
        }]
    }
    
  3. 如果使用“搜索”无法做到这一点,那么是否可以使用二级索引来实现这一点?

4

3 回答 3

5

在 CouchDB 中,您不能将查询参数的动态值传递给视图(在您的情况下为 cat=determination)。CouchDB 中的方法是创建一个更通用的视图,然后在调用视图以获取所需数据时调整结果的排序方式。

您需要在数据库的设计文档中创建自定义视图以实现此目的:

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});
        }
    }
}

所以上面的视图获取数据库中的每个文档,检查它是否有一个包含内容的项目数组,然后循环遍历所有文档的项目。对于它发现它cat作为索引发送到结果集中的每个项目元素,这很重要,因为我们可以根据该索引进行排序。我们可以自由地以我们喜欢的任何方式构建结果对象( 的第二个参数emit),在上述情况下,我正在构建一个带有用户 ID 和项目日期和文本的对象。

您可以像这样调用视图,以获取所有结果:

curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat

如果你只是对索引键(即cat)是“确定”的结果感兴趣,你会这样做:

curl -X GET http://127.0.0.1:5984/<db-name>/_design/<design-doc-name>/_view/byUserItemCat?key="determination"
于 2013-05-02T10:55:08.253 回答
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
于 2014-11-18T02:16:39.120 回答
1

Cloudant 的搜索工作在返回文档的粒度上。您的索引功能可以索引item文档中跨 s 使用的类别,然后您的搜索将返回包含item您提到的类别的 s 的文档。然后,您的应用程序代码将需要过滤到items 以返回给客户端。

您的索引函数将类似于(从 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)。

于 2013-05-09T16:03:21.650 回答