对Azure DocumentDB进行排序

时间:2015-03-30 17:24:29

标签: sorting azure-cosmosdb

我想使用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;
  }
}

2 个答案:

答案 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/