【问题标题】:How do I create a dynamic query using pouchdb (couchdb probably the same thing)?如何使用 pouchdb(couchdb 可能是同一件事)创建动态查询?
【发布时间】:2015-06-04 21:01:03
【问题描述】:

我有一个想要使用 PouchDB 编写的动态查询,但我发现与 PouchDB 相比,我很难解释如何使用 SQL 数据库来实现这一点。

我在 PouchDB 中有许多“会话”类型的文档,需要对这种类型的文档进行复杂的搜索。我想过滤诸如标题(以提供的值开头的字符串)、状态、所有者、设备 ID、开始日期、结束日期和其他一些内容。

现在,我知道我可以发出一个数组键,例如:

            document.views = {
                by_title_status_owner: {
                    map: function(document) {
                        if(document._id.startsWith('session')) {
                            emit([
                                document.title.toUpperCase(),
                                document.status.text.toUpperCase(),
                                document.owner.refId
                            ], null);
                        }
                    }.toString()
                }
            };

我的问题是我不知道如何使用startkeyendkey 进行查询。我正在尝试这样的事情:

                startkey: [
                    (filters.title || '').toUpperCase(),
                    (filters.status || '').toUpperCase(),
                    (filters.owner || '')
                ],
                endkey: [
                    (filters.title || '').toUpperCase() + '\uffff',
                    (filters.status || '').toUpperCase() + '\uffff',
                    (filters.owner || '').toUpperCase() + '\uffff'
                ],

但它似乎只过滤 first 索引 - 这意味着它正确过滤了标题,但是当按状态或所有者搜索时,查询返回所有结果。

我认为问题在于我真的想提供不同的发射数组键并根据用户输入的内容提供不同的开始键/结束键组合,但这似乎很难用 PouchDB 做到。

例如,假设用户为他们的title 搜索输入了“Lig”,并为状态选择了CLOSED。这意味着 startkey 应该看起来像 ['LIG', 'CLOSED'],而 endkey 可能看起来像 ['LIG\uffff', 'CLOSED']。但这是否意味着我必须发出键索引的每一个排列来匹配这个动态的 startkey/endkey?

这是我的第一次尝试,我什至没有添加 2+ 参数发出的键.....

        getAllByCriteria: function(filters) {
            var startkey = [], endkey = [];

            if(filters.title) {
                startkey.push((filters.title || '').toUpperCase());
                endkey.push((filters.title || '').toUpperCase() + '\uffff');
            }

            if(filters.status) {
                startkey.push((filters.status).toUpperCase());
                endkey.push((filters.status).toUpperCase());
            }

            if(filters.owner) {
                startkey.push(filters.owner);
                endkey.push(filters.owner);
            }

            return Database.instance().query('session_indexes/by_criteria', {
                startkey: startkey,
                endkey: endkey,
                include_docs: true
            }).then(function(result) {
                return _(result.rows).map(function(row) {
                    return Session.fromDocument(row.doc, new Session());
                });
            });
        },

和:

        db.upsert('_design/session_indexes', function(document) {
            document.views = {
                by_criteria: {
                    map: function(document) {
                        if(document._id.startsWith('session')) {
                            emit([], null)
                            emit([document.title.toUpperCase()], null);
                            emit([document.status.text.toUpperCase()], null);
                            emit([document.owner.refId], null);
                        }
                    }.toString()
                }
            };

            return document;
        });

我真的很困惑。我会很感激任何帮助。

谢谢!

【问题讨论】:

    标签: javascript couchdb pouchdb


    【解决方案1】:

    您可以使用视图和列表的组合。

    1. 使用映射 fn 发出 ["title", doc.title.toUpperCase()]["status", doc.status.toUpperCase()] 等键,例如 indexfn

    2. 创建_list fn,比如filter,它接受{field1:"value1", field2:"value2"...} 之类的查询——列表可以接收自定义查询参数,这与map fns 不同。如果行不匹配,您的过滤器必须删除它们。为了使过滤成为可能,您的 _list 必须从视图 fn 接收完整(或以某种方式修剪)的字段集。

    3. 执行类似/_design/ddoc/_list/filter/_view/indexfn?startkey=["field1","val1"] & endkey=["field1","val1z"] & filter={"field2":"val2", "field3":"val3"}的请求

    当您的 _list 从视图中接收不超过一千行时,这种方法是合理的 - 从视图通过 _lists fn 将数据管道传输到最终用户非常缓慢。

    因此,如果您有大约 1M 条记录的或多或少按字母顺序分布的数据集,则发送 3 个或更多字符长的 startkey 可以获得良好的性能。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-26
      • 1970-01-01
      • 1970-01-01
      • 2021-09-09
      • 1970-01-01
      • 2015-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多