【问题标题】:couchdb - startkey endkey doesn't filter records with key arrays as expectedcouchdb - startkey endkey 不会按预期过滤带有键数组的记录
【发布时间】:2014-10-28 22:31:33
【问题描述】:

我有输出这个的 Couch-DB map-reduce 视图;

 {
rows: [
    {
        key: [
            "2014-08-20",
            2,
            "registration"
        ],
        value: 2
    },
    {
        key: [
            "2014-08-20",
            2,
            "search"
        ],
        value: 3
    },
    {
        key: [
            "2014-08-21",
            2,
            "registration"
        ],
        value: 3
    },
    {
        key: [
            "2014-08-21",
            2,
            "search"
        ],
        value: 4
    }
]
}

我需要查询2014-08-20和2014-08-21之间的所有记录同时我需要中间的整数值为2,最后一个值为“注册”。

我的 curl 请求 URL 如下所示

BASE_URL?group=true&startkey=["2014-08-20",1,"registration"]
&endkey=["2014-08-21",1,"registration"]

这会过滤掉日期,但不会过滤掉其他元素(整数值和字符串)。有人知道发生了什么吗?

任何帮助将不胜感激。

更新

我的文档结构看起来像这样

[
    {
        platform_version: 2,
        UDID: "EWHSJeNp20sBFuzqcorkKVVi",
        session: {
            timestamp: "2014-08-20T00:00:00.000Z",
            session_id: "kOnNIhCNQ31LlkpEPQ7XnN1D",
            ip: "202.150.213.66",
            location: "1.30324,103.5498"
        },
        events: [
            {
                event_type: "search",
                timestamp: "2014-08-21T00:00:00.000Z",
                location: "1.30354,103.5301",
                attributes: {

                }
            }
        ]
    },
    {
        platform_version: 2,
        UDID: "EWHSJeNp20sBFuzqcorkKVVi",
        session: {
            timestamp: "2014-08-21T00:00:00.000Z",
            session_id: "kOnNIhCNQ31LlkpEPQ7XnN1D",
            ip: "202.150.213.66",
            location: "1.30324,103.5498"
        },
        events: [
            {
                event_type: "search",
                timestamp: "2014-08-21T00:00:00.000Z",
                location: "1.30354,103.5301",
                attributes: {

                }
            }
        ]
    },
    {
        platform_version: 2,
        UDID: "EWHSJeNp20sBFuzqcorkKVVi",
        session: {
            timestamp: "2014-08-20T00:00:00.000Z",
            session_id: "kOnNIhCNQ31LlkpEPQ7XnN1D",
            ip: "202.150.213.66",
            location: "1.30324,103.5498"
        },
        events: [
            {
                event_type: "click",
                timestamp: "2014-08-21T00:00:00.000Z",
                location: "1.30354,103.5301",
                attributes: {

                }
            }
        ]
    }
]

map reduce 函数看起来像这样。

function(doc) {

date = doc.session.timestamp.split("T")[0];
eventArray = doc.events;
for (i = 0; i < eventArray.length; i++) { 

    emit([doc.app_version,eventArray[i].event_type,date],1);

}


}

在我更改键的顺序后它开始工作。但是,我仍然不能使用通配符来查询所有事件类型。

【问题讨论】:

  • BASE_URL 是一个常量,我用它来保存 couchdb 服务器的 URL。

标签: mapreduce couchdb


【解决方案1】:

您获得的文档具有不同的第二个数组项,而不是 1,因为在 CouchDB 中,限制(startkey 和 endkey)与使用 lexicographical order 的映射键进行比较。按字典顺序[1,1] &lt; [1,2] &lt; [2,1] &lt; [2,2]。

您需要的是多维查询(CouchDB 不支持)、额外的客户端过滤(这可能会增加 CouchDB 和您的应用程序之间传输的数据)或使用 list function 的额外服务器端过滤(这会增加处理查询时间)。

如果您的应用需要仅在键数组的第一个元素上使用范围进行过滤(就像在您的示例查询中一样),您可以通过将项目放在数组的最后一个位置来轻松解决您的问题,例如。发出[1, "registration", "2014-08-21"] 而不是["2014-08-21", 1, "registration"]。

【讨论】:

  • Marcin - 谢谢。我需要的是在 2014 年 8 月 20 日和 2014 年 8 月 21 日之间获取所有显示“注册”的记录和数值 1。你认为这可能吗?
  • Marcin - 另外,当我想在中间字符串值上使用通配符时它不起作用,即使我将它作为最后一个元素发出也是如此。例如:startkey=[1, 0, "2014-08-20"] &endkey=[1, {}, "2014-08-21"]
  • 可以通过列表功能过滤掉查询结果。
  • 除了使用列表再次查询之外,还有其他解决方案吗?列表函数是否会比获取 map-reduce 输出和过滤的单独 PHP 脚本更快?
  • 一般情况下通过多维查询解决的问题在 CouchDB 中很困难。根据特定的用例(例如,对预期数据的限制),您通常可以有一个有效的解决方案,可能需要更改数据结构(文档方案)。您没有提供有关您的用例的任何提示,所以我不知道如何为您提供帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
相关资源
最近更新 更多