我想使用DocumentDB存储大约200,000个相同类型的文档。每个文件都得到一个整数id字段,我想以相反的顺序(最高的id优先)检索它们。
所以最近我发现DocumentDB没有排序(另见DocumentDB - query result order)。也许最好去一个不同的数据库(比如RavenDB)但是,时间紧迫,我想避免转换到另一个数据库的成本。
问题: 我一直在寻找在客户端实现我自己的文档排序索引(ASP Web API 2)。我正在考虑创建key(id)和value(document.selflink)的SortedList。然后我可以创建一个带有count,offset和谓词参数的Getter来过滤文档。下面我添加了一个简单的例子。
我只是觉得这是一个坏主意;要么慢,要么花费太多资源,要么可以用另一种方式做得更好。所以我愿意接受实施建议......
public class SortableDocumentDbRepository
{
private SortedList _sorted = new SortedList();
private readonly string _sortedPropertyName;
private DocumentCollection ReadOrCreateCollection(string databaseLink) {
DocumentCollection col = base.ReadOrCreateCollection(databaseLink);
var docs = Client.CreateDocumentQuery(Collection.DocumentsLink)
.AsEnumerable();
lock (_sorted.SyncRoot) {
foreach (Document doc in docs) {
var propVal = doc.GetPropertyValue<string>(_sortedPropertyName);
if (propVal != null) {
_sorted.Add(propVal, doc.SelfLink);
}
}
}
return col;
}
public List<T> GetItems<T>(int count, int offset, Expression<Func<T, bool>> predicate) {
List<T> result = new List<T>();
lock (_sorted.SyncRoot) {
var values = _sorted.GetValueList();
for (int i = offset; i < _sorted.Count; i++) {
var queryable = predicate != null ?
Client.CreateDocumentQuery<T>(values[i].ToString()).Where(predicate) :
Client.CreateDocumentQuery<T>(values[i].ToString());
T item = queryable.AsEnumerable().FirstOrDefault();
if (item == null || item.Equals(default(T))) continue;
result.Add(item);
if (result.Count >= count) return result;
}
}
return result;
}
}
答案 0 :(得分:4)
Microsoft已实施排序: https://docs.microsoft.com/en-us/azure/cosmos-db/sql-api-sql-query-reference#bk_orderby_clause
示例:SELECT * FROM c ORDER BY c._ts DESC
答案 1 :(得分:2)
正如您所提到的,不幸的是,订单尚未实施。
你的方法对我来说很合理。
我看到你正在使用谓词来缩小查询结果集(为任何数据库提取200,000条记录都会很昂贵)。
由于看起来您希望按id
订购 - 您还可以查看在id
上设置范围索引,以便您执行范围查询(例如<
和>
上id
}并进一步缩小查询结果集。默认情况下,文档的_ts
(时间戳)系统属性中还包含一个范围索引,在此上下文中也可能会有所帮助。
请参阅:http://azure.microsoft.com/en-us/documentation/articles/documentdb-indexing-policies/