Android CouchBase Lite,排除查询中具有特定键的文档

Android CouchBase Lite,排除查询中具有特定键的文档,android,couchbase,couchbase-lite,couchbase-view,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, E

我有一个带有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);
    }
com.couchbase.lite.View=database.getView(视图名称);
if(view.getMap()==null){
映射器映射=新映射器(){
@凌驾
公共空心地图(地图文档、发射器){
if(“user”.equals(document.get(“type”)){
emit(document.get(“name”),document);
}
}
};
view.setMap(map,null);
}
有了这个视图,我可以在它上面创建查询,使用某些参数,如setKeys、startKey、endKey、setDescending、setDescending、setSkip和couchbase中描述的其他参数

如果我写

    Query query = view.createQuery();
    List<Object> keys = new ArrayList<>();
    keys.add("User Name");
    query.setKeys(keys);
Query Query=view.createQuery();
列表键=新的ArrayList();
密钥。添加(“用户名”);
查询。设置键(键);
该查询将返回与“用户名”键匹配的所有文档

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

一名黑客被发现在 代码如下所示:

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;
}
publicstaticquerygetquery(数据库,最终字符串ignoreUserId){
com.couchbase.lite.View=database.getView(视图名称);
if(view.getMap()==null){
映射器映射=新映射器(){
@凌驾
公共空心地图(地图文档、发射器){
if(“user”.equals(document.get(“type”)){
如果(ignoreUserId==null||
(ignoreUserId!=null&&
!ignoreUserId.equals(document.get(“user_id”)){
emit(document.get(“name”),document);
}
}
}
};
view.setMap(map,null);
}
Query=view.createQuery();
返回查询;
}
请注意,该视图将仅排除您在第一次调用期间传递给它的键ignoreUserId,并将在下一次调用期间忽略所有其他项(因为它将在第一次调用期间仅创建一次视图)

因此,您需要为每个要忽略的键创建新视图。 但是,如果您有很多要排除的密钥,或者经常这样做,那么这将是低效的和陈词滥调的

你知道更好的解决方法吗

感谢您的帮助

提前感谢

CouchBase不是为您希望在此处发布的查询类型而设计的。它的设计目的是使用引擎盖下的map/reduce来识别特定文档,范围为(下至1个文档),而不是排除特定文档。你所问的问题在CouchBase中是没有效率的。如果您的目标是高效地执行此类查询,那么您使用的技术是错误的

但是,如果您的双手被束缚,并且被锁定在CouchBase Lite中,那么您必须在现有的查询类型中工作。排除某个特定值可以重新表述为包括所有其他值。如果要在CouchBase中执行此操作,可以使用范围查询,范围设计为不包含要排除的值

下面是一个简单的概念示例。假设视图中有键为“A”、“B”、“C”、“D”、“F”和“X”的文档,并且希望发出一个查询,其结果不包括文档“D”。您可以通过首先对“a”-“C”发出范围查询,然后对“E”-“Z”发出第二个范围查询来获得所需的结果。这两个结果加起来将是除“D”之外的所有结果


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

非常感谢您的回答,这个主题似乎不太重要popular@hrunting这个答案完全错误,这正是N1QL Couchbase内部类似SQL的查询语言跳跃的地方in@FrankfromDSPEED截至2016年6月,Couchbase Lite不支持使用N1QL。正在添加相关更新。在v2.0中,Couchbase Lite将支持动态查询(即N1QL)。