CouchBase Lite,在查询中排除包含某些键的文档

时间:2014-07-23 10:53:58

标签: android couchbase couchbase-lite couchbase-view

我有一个使用mapper的简单视图,可以使用某些键发出文档。

    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    emitter.emit(document.get("name"), document); 
                }
            }
        };
        view.setMap(map, null);
    }

有了这个View,我可以创建查询,使用setKeys,startKey,endKey,setDescending,setDescending,setSkip等特定参数,如couchbase manual中所述。

如果我写

    Query query = view.createQuery();
    List<Object> keys = new ArrayList<>();
    keys.add("User Name");
    query.setKeys(keys);

该查询将返回与“用户名”密钥匹配的所有文档。

但我找不到一种简单的方法来编写用某些键排除(省略)文档的查询(与setKeys()函数相反)

ToDoLite Example找到了一个黑客攻击 代码如下所示:

public static Query getQuery(Database database, final String ignoreUserId) {
    com.couchbase.lite.View view = database.getView(VIEW_NAME);
    if (view.getMap() == null) {
        Mapper map = new Mapper() {
            @Override
            public void map(Map<String, Object> document, Emitter emitter) {
                if ("user".equals(document.get("type"))) {
                    if (ignoreUserId == null ||
                            (ignoreUserId != null &&
                                    !ignoreUserId.equals(document.get("user_id")))) {
                        emitter.emit(document.get("name"), document);
                    }
                }
            }
        };
        view.setMap(map, null);
    }

    Query query = view.createQuery();
    return query;
}

请注意,该视图将仅排除您在第一次调用期间传递给它的键 ignoreUserId ,并在下次调用期间忽略所有其他键(因为它将在第一次调用期间仅创建一次视图)

因此,您需要为要省略的每个键创建新视图。 但是如果你想要排除或经常使用很多密钥,那么效率和样板效率都会很低。

你知道更好的解决方案还是黑客攻击?

任何帮助表示赞赏 提前致谢

1 个答案:

答案 0 :(得分:4)

CouchBase不适用于您要在此处发布的查询类型。它旨在使用引擎盖下的map / reduce来识别具有范围(低至1个文档范围)的特定文档,而不是排除特定文档。你问的问题在CouchBase中不会有效。如果您的目标是有效地执行这些类型的查询,那么您使用的是错误的技术。

如果您的双手被束缚而且您被锁定在CouchBase Lite中,则必须使用您所拥有的查询类型。排除特定值可以重新包括所有其他值。如果您想在CouchBase中执行此操作,则可以使用范围查询,其范围设计为不包括您要排除的值。

这是一个简短的概念性例子。假设您的视图包含带有“A”,“B”,“C”,“D”,“F”和“X”键的文档,并且您希望发出一个结果不包含文档“D”的查询。您可以通过首先发出“A” - “C”的范围查询,然后发出“E” - “Z”的第二个范围查询来获得所需的结果。结合的两个结果将是除“D”之外的所有内容。

当然,这些都是简单的按键。键越复杂,范围端点变得越复杂,以排除特定值。要排除的密钥越多,您必须执行的查询越多(您必须对N个排除的术语执行N + 1个查询)。您可能会通过查询视图中的所有值并自己过滤代码来获得更高效的系统。