Mongodbの10億レベルのデータ操作

最近、会社のビジネス関係のために、毎日300w +データが必要であり、Double Elevenピーク期間中の3000w +データは迅速にクエリされてダンプされます。このプロセスでは、古いデータの総量が3億2,000万近くあるため、クエリは頭痛の種です。クエリが不適切である場合、Mongodbは誤って破棄され、データベースを削除して実行するという悲劇的な傾向があります。

基本条件:

SpringBootプロジェクト

依存関係を導入する:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

// application.yml引入配置
data:
  mongodb:
    uri: mongodb://root:123565@localhost:27017/admin

難しさ:

  • クエリの最適化
  • データストレージの最適化
  • 非同期プログラミングデータセキュリティ

スキーム:

  1. クエリはデータの総量を同期する必要があります
  2. Mysqlが当日に分割されているかどうかを照会する
  3. 日付条件に従って、商人、ユーザー、バッチごとにグループ化して問い合わせます
  4. 最終的なマーチャント、ユーザー、バッチ、および日付に対して条件付きクエリを実行して、同期するバッチの総数(数値)を計算します
  5. 最終的なマーチャント、ユーザー、バッチ、および日付に対して条件付きクエリを実行してIDで並べ替えます(1つのクエリのみが必要であり、フォーカスはIDによる昇順での並べ替え)
  6. ページングを使用してページごとのクエリ数をクエリしてから同期する(たとえば、pageSize = 1w、同期する必要があるpageCount = num / pageSize +1)
  7. ページングクエリを使用しますが、スキップ+制限クエリを使用しないでください(スキップ+制限データが大きい場合、mongodb接続タイムアウトが発生し、他のクエリサービスを実行できません)。スキップ効率が低すぎるため、クエリの現在のIDと制限pageSizeよりも大きい値を使用します
  8. 各クエリの前にIDの最後のデータのデータへの更新クエリID交換すること

会社のセキュリティが関係しているため、コードの一部のみ(=。=)を提供できます

データ同期単一テーブルクエリのストレージ効率は(10w + /分)

Mongodbオペレーション

1.条件+グループクエリ

Criteria criteria = new Criteria();
criteria.andOperator(
    Criteria.where("createDate").gte(new Date(startDate)),
    Criteria.where("createDate").lt(new Date(endDate))
                );
Aggregation aggregation = Aggregation.newAggregation(
                    Aggregation.match(criteria),
                    Aggregation.group("userId").count().as("count")
            ).withOptions(AggregationOptions.builder().allowDiskUse(true).build());
List<Map> list = mongoTemplate.aggregate(aggregation, item, Map.class).getMappedResults();

2.基本的な複数条件クエリ

Criteria criteria = new Criteria();
// 等于条件     (mysql:=)
criteria.and("userName").is(queryForm.getUserName());
// 模糊条件查询  (mysql:like ('%content%'))
criteria.and("content").regex(queryForm.getContent(), "i");
// 大于等于条件  (mysql:>=)
criteria.and("createDate").gte(DateUtil.beginOfDay(queryForm.getStartDate()));
// 小于等于条件  (mysql:<=)
criteria.and("createDate").lte(DateUtil.endOfDay(queryForm.getEndDate()));
// 分页查询
int start = (pageNum - 1) * pageSize;
int limit = pageSize;
Query query = new Query(criteria).with(Sort.by(Sort.Direction.DESC, "createDate")).skip(start).limit(limit);

 

25件の元の記事を公開 Like9 460,000以上にアクセス

おすすめ

転載: blog.csdn.net/qq_31150503/article/details/105451876