Couchbase Lite - 按值排序 Map/Reduce
Couchbase Lite - Sorting Map/Reduce by values
广告:我正在使用 CouchbaseLite Android 1.4.0,我还没有准备好切换到 2.0。
要了解我的问题的背景:
- 我有 2 种文档类型:
PATIENT
& VISIT
- 一位患者通过一个字段链接到一次就诊
visitId
- 一次访问有
startDateTime
和 endDateTime
- 如果
endDateTime
为空或缺失 ,则访问被视为 'open'
- 一次访问可以通过字段
visitType
进行不同类型的访问
- 可以通过字段
inactive
使访问无效
我想:
- 获取某种类型的所有开放和活跃访问的所有患者(id + 姓名)
- 结果使用
skip
和 limit
分页
- 获取按名称排序的结果
我设法得到所有正确的患者并对结果进行分页,但问题在于排序。
由于分页,我无法制作 'post sorting'(以随机顺序获取结果,然后使用自制方法对它们进行排序)。
下面是它在没有排序的情况下的实际工作方式:
MAP/REDUCE
if (isVisit()) {
Object inactive = document.get(FIELDS.INACTIVE);
if(inactive == null)
inactive = false;
Document patientDoc = database.getExistingDocument(FIELDS.PATIENT_ID);
if(patientDoc != null && patientDoc.getProperties() != null) {
Object[] keys = {
document.get(CouchbaseVisitManager.FIELDS.STOP_DATE_TIME),
inactive,
document.get(CouchbaseVisitManager.FIELDS.VISIT_TYPE)
};
Object[] values = {
document.get(FIELDS.PATIENT_ID),
patientDoc.getProperties().get(FIELDS.FAMILY_NAME),
patientDoc.getProperties().get(FIELDS.FIRST_NAME)
}
emitter.emit(keys, values);
}
}
查询
Query query = getQuery(Views.PATIENTS_CURRENTLY_IN_VISIT); //Helper method to create a query
query.setKeys(new ArrayList<Object>(){{
add(new ArrayList<Object>(){{
add(null);
add(false);
add(visitType);
}});
}});
query.setSkip(skip);
query.setLimit(limit);
这对吸引我的病人很有效,但对他们进行分类却效果不佳。
我尝试在视图中添加患者姓名,如下所示:
Object[] keys = {
patientDoc.getProperties().get(FIELDS.FAMILY_NAME),
patientDoc.getProperties().get(FIELDS.FIRST_NAME),
document.get(FIELDS.STOP_DATE_TIME),
inactive,
document.get(FIELDS.VISIT_TYPE)
};
并像这样更新我的 query.keys
:
query.setStartKey(new ArrayList<Object>(){{
add(null);
add(null);
add(null);
add(false);
add(visitType);
}});
query.setEndKey(new ArrayList<Object>(){{
add(new HashMap<>());
add(new HashMap<>());
add(null);
add(false);
add(visitType);
}});
但是这个returns没有患者(result.size = 0)
所以...我不知道如何实现我的目标。
我想出了一种按值排序的方法,但它似乎还不存在(我认为应该等待 2.0)。但是他们有任何解决方法来实现这种行为吗?
感谢阅读。
查看结果始终按键排序。所以你应该将患者姓名添加到键中,然后你就会得到你的排序。
请注意将名称放入键数组的正确位置,因为排序是按字典顺序排列的,也就是说,如果名称将成为最后一个组件,那么您将按名称对所有打开的非活动状态进行排序,然后所有打开的活动按名称 e.t.c.
排序
如果您需要将您的姓名键放在其他键的前面但仍然能够过滤您的结果,那么您将需要正确构造开始键和结束键,以便每个键的完整范围可能的患者姓名将被接受,而后面的键将被过滤。
您将必须提供一些肯定小于或大于任何可能的患者姓名的值。
遵循为 Couchbase 视图定义的 key collation,null
将始终小于任何字符串,空映射 {}
可用于匹配最后一个字符串。您基本上在上一个样本中做对了。
如果您想以反向模式查询视图,请不要忘记切换开始和结束键逻辑
另一件需要注意的事情是在更改其逻辑或键集后始终增加视图的版本,否则您将继续获得旧结果。增加版本将强制刷新视图,对所有数据执行视图函数中的更新逻辑。
广告:我正在使用 CouchbaseLite Android 1.4.0,我还没有准备好切换到 2.0。
要了解我的问题的背景:
- 我有 2 种文档类型:
PATIENT
&VISIT
- 一位患者通过一个字段链接到一次就诊
visitId
- 一次访问有
startDateTime
和endDateTime
- 如果
endDateTime
为空或缺失 ,则访问被视为 'open'
- 一次访问可以通过字段
visitType
进行不同类型的访问
- 可以通过字段
inactive
使访问无效
我想:
- 获取某种类型的所有开放和活跃访问的所有患者(id + 姓名)
- 结果使用
skip
和limit
分页
- 获取按名称排序的结果
我设法得到所有正确的患者并对结果进行分页,但问题在于排序。 由于分页,我无法制作 'post sorting'(以随机顺序获取结果,然后使用自制方法对它们进行排序)。
下面是它在没有排序的情况下的实际工作方式:
MAP/REDUCE
if (isVisit()) {
Object inactive = document.get(FIELDS.INACTIVE);
if(inactive == null)
inactive = false;
Document patientDoc = database.getExistingDocument(FIELDS.PATIENT_ID);
if(patientDoc != null && patientDoc.getProperties() != null) {
Object[] keys = {
document.get(CouchbaseVisitManager.FIELDS.STOP_DATE_TIME),
inactive,
document.get(CouchbaseVisitManager.FIELDS.VISIT_TYPE)
};
Object[] values = {
document.get(FIELDS.PATIENT_ID),
patientDoc.getProperties().get(FIELDS.FAMILY_NAME),
patientDoc.getProperties().get(FIELDS.FIRST_NAME)
}
emitter.emit(keys, values);
}
}
查询
Query query = getQuery(Views.PATIENTS_CURRENTLY_IN_VISIT); //Helper method to create a query
query.setKeys(new ArrayList<Object>(){{
add(new ArrayList<Object>(){{
add(null);
add(false);
add(visitType);
}});
}});
query.setSkip(skip);
query.setLimit(limit);
这对吸引我的病人很有效,但对他们进行分类却效果不佳。
我尝试在视图中添加患者姓名,如下所示:
Object[] keys = {
patientDoc.getProperties().get(FIELDS.FAMILY_NAME),
patientDoc.getProperties().get(FIELDS.FIRST_NAME),
document.get(FIELDS.STOP_DATE_TIME),
inactive,
document.get(FIELDS.VISIT_TYPE)
};
并像这样更新我的 query.keys
:
query.setStartKey(new ArrayList<Object>(){{
add(null);
add(null);
add(null);
add(false);
add(visitType);
}});
query.setEndKey(new ArrayList<Object>(){{
add(new HashMap<>());
add(new HashMap<>());
add(null);
add(false);
add(visitType);
}});
但是这个returns没有患者(result.size = 0)
所以...我不知道如何实现我的目标。 我想出了一种按值排序的方法,但它似乎还不存在(我认为应该等待 2.0)。但是他们有任何解决方法来实现这种行为吗?
感谢阅读。
查看结果始终按键排序。所以你应该将患者姓名添加到键中,然后你就会得到你的排序。
请注意将名称放入键数组的正确位置,因为排序是按字典顺序排列的,也就是说,如果名称将成为最后一个组件,那么您将按名称对所有打开的非活动状态进行排序,然后所有打开的活动按名称 e.t.c.
排序如果您需要将您的姓名键放在其他键的前面但仍然能够过滤您的结果,那么您将需要正确构造开始键和结束键,以便每个键的完整范围可能的患者姓名将被接受,而后面的键将被过滤。 您将必须提供一些肯定小于或大于任何可能的患者姓名的值。
遵循为 Couchbase 视图定义的 key collation,null
将始终小于任何字符串,空映射 {}
可用于匹配最后一个字符串。您基本上在上一个样本中做对了。
如果您想以反向模式查询视图,请不要忘记切换开始和结束键逻辑
另一件需要注意的事情是在更改其逻辑或键集后始终增加视图的版本,否则您将继续获得旧结果。增加版本将强制刷新视图,对所有数据执行视图函数中的更新逻辑。