使用 MapReduce 视图查询 Couchbase Lite 问题
Querying Couchbase Lite problems using MapReduce Views
我一直在努力解决与在我的移动 Android 设备上查询 Couchbase lite 1.4 数据库相关的问题。在我看来,我并不完全理解使用 MapReduce Views 进行查询的方式。
所以我有以下设置:
1) 包含如下实体的数据库:
{
dateCreated: 1220227200,
relatedObjectId: "objectId_23445"
type: "mytype"
}
2) 我想查询我的数据库并获取类型为“mytype”的所有对象,这些对象与具有给定 ID 的对象相关(relatedObjectId 字段)并按 dateCreated 字段排序。
这是生成视图的地图函数:
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);
所以我需要这方面的帮助。在我看来,我只是不明白当键是复合键(在我的例子中是 arrayList)时如何过滤对象。
Ofc 作为解决方法,我只能发出 relatedObjectId,然后手动对数据进行排序,但这是正确的方法吗?
任何帮助将不胜感激,在此先感谢!
经过一些额外的研究(包括一些关于 Whosebug 的帖子),我解决了我的问题。
似乎为了实现我想要的首先我必须在 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() 函数产生以下输出:
[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);
现在我的查询将首先 select 所有具有 relatedObjectId 的元素,然后对这个序列进行排序,因为我们将始终为所有元素使用相同的前缀 (relatedObjectId), 排序时将考虑第二项 (dateCreated).
我一直在努力解决与在我的移动 Android 设备上查询 Couchbase lite 1.4 数据库相关的问题。在我看来,我并不完全理解使用 MapReduce Views 进行查询的方式。
所以我有以下设置:
1) 包含如下实体的数据库:
{
dateCreated: 1220227200,
relatedObjectId: "objectId_23445"
type: "mytype"
}
2) 我想查询我的数据库并获取类型为“mytype”的所有对象,这些对象与具有给定 ID 的对象相关(relatedObjectId 字段)并按 dateCreated 字段排序。
这是生成视图的地图函数:
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);
所以我需要这方面的帮助。在我看来,我只是不明白当键是复合键(在我的例子中是 arrayList)时如何过滤对象。
Ofc 作为解决方法,我只能发出 relatedObjectId,然后手动对数据进行排序,但这是正确的方法吗?
任何帮助将不胜感激,在此先感谢!
经过一些额外的研究(包括一些关于 Whosebug 的帖子),我解决了我的问题。
似乎为了实现我想要的首先我必须在 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() 函数产生以下输出:
[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);
现在我的查询将首先 select 所有具有 relatedObjectId 的元素,然后对这个序列进行排序,因为我们将始终为所有元素使用相同的前缀 (relatedObjectId), 排序时将考虑第二项 (dateCreated).