2017-03-01 13 views
2

私はAzure DocumentDBを使用してMongoDBコレクションを操作しています。.NETドライバでAzure DocumentDBでMongoDBを使用するとMongoCommandExceptionがスローされる

私はAzure標準計画に従って1000 RU/sの制限を設けています。

MongoDBコレクションから一部のデータをフィルタリングして並べ替えるときに発生する問題が発生します。ここで

は、.NETのMongoDBドライバ2.4.2.0使用して、私のC#のコードです:?私はルートAPI /映画と私のコントローラを呼び出すと

// GET api/movies 
    [HttpGet] 
    public async Task<IActionResult> Get([RequiredFromQuery] int page, [FromQuery] int limit, 
     [FromQuery] string quality, [FromQuery] int minimumRating, [FromQuery] string queryTerm, [FromQuery] string genre, [FromQuery] string sortBy, [FromQuery] string orderBy) 
    { 
     var nbMoviesPerPage = 20; 
     if (limit >= 20 && limit <= 50) 
     { 
      nbMoviesPerPage = limit; 
     } 

     var currentPage = 1; 
     if (page >= 1) 
     { 
      currentPage = page; 
     } 

     var movies = _mongoDbService.GetCollection(Constants.MoviesCollectionName); 
     var filter = Builders<MovieBson>.Filter.Empty; 
     var sort = Builders<MovieBson>.Sort.Descending(movie => movie.DateUploadedUnix); 

     if (!string.IsNullOrWhiteSpace(quality) && 
      (quality == "720p" || quality == "1080p" || quality.ToLower() == "3d")) 
     { 
      filter = filter & Builders<MovieBson>.Filter.Eq("torrents.quality", quality); 
     } 

     if (minimumRating > 0 && minimumRating < 10) 
     { 
      filter = filter & Builders<MovieBson>.Filter.Gt("rating", minimumRating); 
     } 

     if (!string.IsNullOrWhiteSpace(queryTerm)) 
     { 
      filter = filter & 
        (Builders<MovieBson>.Filter.Regex("imdb_code", new BsonRegularExpression("/^" + queryTerm + "$/i")) | 
         Builders<MovieBson>.Filter.Regex("title", new BsonRegularExpression("/^" + queryTerm + "$/i")) | 
         Builders<MovieBson>.Filter.Regex("cast.name", new BsonRegularExpression("/^" + queryTerm + "$/i")) | 
         Builders<MovieBson>.Filter.Regex("cast.imdb_code", new BsonRegularExpression("/^" + queryTerm + "$/i"))); 
     } 

     if (!string.IsNullOrWhiteSpace(genre)) 
     { 
      filter = filter & Builders<MovieBson>.Filter.In("genres", new List<string> 
      { 
       genre 
      }); 
     } 

     if (!string.IsNullOrWhiteSpace(sortBy)) 
     { 
      switch (sortBy) 
      { 
       case "title": 
        sort = Builders<MovieBson>.Sort.Ascending(movie => movie.Title); 
        break; 
       case "year": 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.Year); 
        break; 
       case "rating": 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.Rating); 
        break; 
       case "peers": 
        sort = 
         Builders<MovieBson>.Sort.Descending(movie => movie.Torrents.Select(torrent => torrent.Peers)); 
        break; 
       case "seeds": 
        sort = 
         Builders<MovieBson>.Sort.Descending(movie => movie.Torrents.Select(torrent => torrent.Seeds)); 
        break; 
       case "download_count": 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.DownloadCount); 
        break; 
       case "like_count": 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.LikeCount); 
        break; 
       case "date_added": 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.DateUploadedUnix); 
        break; 
       default: 
        sort = Builders<MovieBson>.Sort.Descending(movie => movie.DateUploadedUnix); 
        break; 
      } 
     } 

     var filteredMovies = movies.Find(filter); 
     var totalTask = filteredMovies.CountAsync(); 
     var moviesTask = filteredMovies.Skip((currentPage - 1) * nbMoviesPerPage).Limit(nbMoviesPerPage).Sort(sort).ToListAsync(); 
     await Task.WhenAll(totalTask, moviesTask); 

     if (!string.IsNullOrWhiteSpace(orderBy)) 
     { 
      switch (orderBy) 
      { 
       case "desc": 
        moviesTask.Result.Reverse(); 
        break; 
      } 
     } 

     return 
      Json(new MovieResponse 
      { 
       TotalMovies = totalTask.Result, 
       Movies = JsonConvert.DeserializeObject<IEnumerable<MovieJson>>(moviesTask.Result.ToJson()) 
      }); 
    } 

をページ= 1 & queryTerm =タイタニック、MongoDBのコマンド出力は:

{find {{"$ [{" {imdb_code ":/^TitaniC $/i}、{タイトル":/^TitaniC $/i}、{"cast.name" skip(0).limit(20)}

{0} $ {i}} $ {i}

と思われ、適切なドキュメントを取得します。

しかし、かなり不規則に、私は私に言っアズールから429 HTTPエラーを取得:

「コマンドが失敗した見つける:、しかし

メッセージ:{[ "リクエスト率が大きい"] "エラー"} APIを一度呼び出すと、他のリクエストはありません。

+0

返品ヘッダーを見て、クエリの費用の見積もりを確認しましたか? 1秒以内に1000RU以上を燃やすと、スロットルが減ります。しかし、あなたがあなたのクエリ/クエリのRUコストを見ない限り、実際には分かりません。 –

+0

私はRUを見ていきますが、Azureポータルのリクエストチャートを見ていますが、ここには表示されていません。https://i.imgsafe.org/71fb51d0bc.jpeg – Ben

答えて

1

MongoDBがインデックスを使用してクエリのソート順を取得できない場合、その結果をメモリにソートします。並べ替え操作が32 MBを超えると、上記のエラーがスローされます。この問題を解決する方法の1つは、allowDiskUseオプションを使用して集約パイプラインステージでデータを一時ファイルに書き込むことです。チェックアウトMy blog for details

var data = await movies.Aggregate(new AggregateOptions 
     { 
      AllowDiskUse = true, 
     }) 
      .Match({})//Insert your query here 
      .Skip(2) 
      .Sort({ "_id", -1 })//Insert your sort options here 
      .Limit(20) 
      .ToListAsync(); 
+0

それはトリックです!ありがとう – Ben

関連する問題