SQL对比聚合框架

SQL 聚合框架操作
select * $project,$group函数
from db.collection.aggregate
join $unwind
where $match
group $group
having $match
limit $limit,$skip
order $sort
  • group

    db.books.aggregate([{
    '$group':{'_id':'$bookcover','cnt':{'$sum':1}}
    }])
    
  • 一对多联表查询

    db.countryCode.aggregate([
    { $lookup: {from: "countryCodeLookup", localField: "code", foreignField: "code", as: "countryName"} },
    { $project: {"code":1, "countryName.name":1, "_id":0} },
    { $match:{"code":1.0}}
    ])
    

上面通过 $lookup 操作符连接两个集合,其中 $project 会过滤属性,$match 作为条件匹配对应的结果

  • 一对一联表查询

    db.countryCode.aggregate([
    { $lookup: {from: "countryCodeLookup", localField: "code", foreignField: "code", as: "countryName"} },
    { $project: {"code":1, "countryName.name":1, "_id":0} },
    { $unwind: "$countryName"},
    { $match:{"code":1.0}}
    ])
    
  • 分页联表查询

    db.bookshelf.aggregate(
    { $match: {"user_id":0,"book_state":1} }, // 搜寻条件
    { $sort: {"last_read_at":1} }, // 排序,1正序,-1倒序
    { $skip: 5 }, // 跳过5条
    { $limit: 10 }, // 取10条件,$limit需要放在$skip后面
    {
    $lookup:
     {
       from: "books", // 要关联查询的表
       localField: "book_id", // 主表用来关联从表的字段
       foreignField: "_id", // 从表用来响应关联的字段
       as: "book" // 将结果重命名为
     }
    },
    { $project: {"_id":0,"book_id":0} }, // 需要过虑的字段
    { $unwind: "$book"}, // 将关联查询的结果转为文档,不加这行关联查询返回的是数组
    )
    
  • 联表查询条件引用字段

    db.bookshelf.aggregate(
    //{ $sort: {"last_read_at":1} },
    //{ $skip: 5 },
    //{ $limit: 10 },
    {
    $lookup:
     {
       from: "books",
       localField: "book_id",
       foreignField: "_id",
       as: "book"
     }
    },
    {
    $match: 
    {
        $expr: {
            $lt: ["book.book_last_process_updated_at", "last_read_at"]
        }
    }
    }
    //{ $unwind: "$book"}, 
    //{ $project: {"_id":0,"book_id":1}}
    )
    
  • 如何从MongoDB中的子文档数组中只返回一个匹配的子文档(而不是数组)? 可以使用以下聚合:

db.col.aggregate([
    { $match: { "valueList.id": "yy3" } },
    { $unwind: "$valueList" },
    { $match: { "valueList.id": "yy3" } },
    { $replaceRoot: { newRoot: "$valueList" } }
])

首先$match将过滤掉所有不必要的文档,然后您可以使用$unwind来获取每个文档的valueList项,然后再次使用$match来仅获取在最后阶段使用yy3的文档。您可以使用$replaceRootvalueList项提升到顶层。

  • golang中使用aggregate ```go opts := &options.AggregateOptions{}
    aggregate := mongo.Pipeline{
    {
    {"$match", filter},
    },
    {
    {"$unwind", "$content"},
    },
    {
    {"$match", filter},
    },
    // {{"$group", bson.D{{"_id", "$state"}, {"totalPop", bson.D{{"$sum", "$pop"}}}}}},
    {
    {"$group",
    bson.D{
    {"_id", "$_id"},
    {"component", bson.D{{"$first", "$component"}}},
    {"text", bson.D{{"$first", "$text"}}},
    {"typename", bson.D{{"$first", "$typename"}}},
    {"updatetime", bson.D{{"$first", "$updatetime"}}},
    {"content", bson.D{{"$push", "$content"}}},
    },
    },
    },
    {
    {"$sort", bson.D{{"updatetime", -1}}},
    },
    {
    {"$skip", page.PageSize * page.Page},
    },
    {
    {"$limit", page.PageSize},
    },
    }

cur, err := core.Mongo.Db.Collection("realtime").Aggregate(c, aggregate, opts)
if err != nil {
return
}


直接进行数组查询,这种查询只要有一个数组元素匹配成功,则整个节点都会返回
```js
db.realtime.aggregate([
	{
		$match: {
			"content": {     
				$elemMatch: {
					$or:[{word: { $regex: "美国" }},{query: { $regex: "美国" }},]
				}
			}
		}
	},
	{
    $project: {
      formatted_date: {
        $dateToString: {
          format: "%Y-%m-%d",
          date: {$toDate: {$multiply: [1000, {$toDouble: "$updatetime"}]}}
        }
      },
      content: "$content",
			updatetime:"$updatetime"
    }
  },
  {
    $group: {
      _id: "$formatted_date",
			updatetime:{$first:"$updatetime"},
      content: {$first: "$content"}
    }
  },
	{
		$sort:{updatetime:1}
	}
])