使用MapReduce视图查询Couchbase Lite问题

时间:2018-04-29 09:47:54

标签: java android couchbase couchbase-lite couchbase-view

我一直在努力解决与在我的移动Android设备上查询Couchbase lite 1.4数据库相关的问题。在我看来,我并不完全理解使用MapReduce Views查询是如何工作的。

所以我有以下设置:

1)包含如下实体的数据库:

{
  dateCreated: 1220227200,
  relatedObjectId: "objectId_23445"
  type: "mytype"
}

2)我想查询我的数据库并获取“ mytype ”类型的所有对象,这些对象与具有给定id( relatedObjectId 字段)的对象相关,并且按 dateCreated 字段排序。

这是我的map函数,它生成一个视图:

public void map(Map<String, Object> document, Emitter emitter) {
  if (document.get("type") != null && document.get("type").equals("mytype")) {
                            List<Object> keys = new ArrayList<Object>();
                            keys.add(document.get("dateCreated");
                            keys.add(document.get("relatedObjectId"));
                            emitter.emit(keys, null);
   }
}

3)此函数产生如下结果:

[1220227200, objectId_23445],
[1220227201, objectId_3],
[1220227202, objectId_7],
[1220227203, objectId_8],
[1220227204, objectId_23445]

4)我希望所有ID为“ objectId_23445 ”的对象按日期排序,如下所示:

[1220227200, objectId_23445],   
[1220227204, objectId_23445]

5)但结果我总是从数据库中获取所有对象。

首先 dateCreated 似乎被考虑在内,但我的第二部分键( relatedObjectId )并没有真正参与过滤。所以我总是从第3点得到一个清单。

我的查询如下:

String relatedObjectId = "objectId_23445"
    Query query = CouchbaseViews.GetAllMyTypeItems().createQuery();            
            query.setDescending(true);

            ArrayList<Object> startKey = new ArrayList<Object>();
            startKey.add(0);
            startKey.add(relatedObjectId );

            ArrayList<Object> endKey = new ArrayList<Object>();
            endKey.add(Calendar.getInstance().getTimeInMillis());
            endKey.add(relatedObjectId );

            query.setStartKey(endKey);
            query.setEndKey(startKey);

所以我需要帮助。在我看来,我只是不明白当key是复合键时我是如何过滤对象的(在我的例子中是arrayList)。

Ofc作为一种解决方法我只能发出 relatedObjectId ,然后手动对数据进行排序,但这是否正确?

任何帮助将不胜感激,提前谢谢!

1 个答案:

答案 0 :(得分:1)

经过一些额外的研究(包括stackoverflow上的一些帖子)后,我解决了我的问题。

似乎为了实现我想要的首先我必须在 map()函数中反转一个订单:

public void map(Map<String, Object> document, Emitter emitter) {
  if (document.get("type") != null && document.get("type").equals("mytype")) {
                            List<Object> keys = new ArrayList<Object>();    
                            //order of elements have been changed                        
                            keys.add(document.get("relatedObjectId"));
                            keys.add(document.get("dateCreated");
                            emitter.emit(keys, null);
   }
}

在这次修改之后,我们的map()函数产生了followig输出:

[objectId_23445, 1220227200],
[objectId_3, 1220227201],
[objectId_7, 1220227202],
[objectId_8, 1220227203],
[objectId_23445, 1220227204]

最后我必须修改我的查询:

String relatedObjectId = "objectId_23445"
    Query query = CouchbaseViews.GetAllMyTypeItems().createQuery();            
            query.setDescending(true);

            ArrayList<Object> startKey = new ArrayList<Object>();            
        startKey.add(relatedObjectId );

            ArrayList<Object> endKey = new ArrayList<Object>();
            endKey.add(relatedObjectId );
        endKey.add(new HashMap<>());

            query.setStartKey(endKey);
            query.setEndKey(startKey);

现在我的查询将首先选择带有 relatedObjectId 的所有元素,然后对此序列进行排序,因为我们将始终为所有元素( relatedObjectId )提供相同的前缀,第二个排序期间将考虑项目( dateCreated )。