我的mongodb集合中的一個檔案如下:
{
"transaction_id": "e10cc8d64204394cd35329a88dc4ab8f",
"timestamp": "2021-05-11 17:47:50",
"client_id": "[email protected]",
"ip": "172.69.34.31",
"level": "OK",
"request": {
"method": "POST",
"status_code": 200,
"status_name": "Ok",
"url": "/ocr/driver"
},
"bytes": 297,
"message": "Status authenticated successfully"
},
{
"transaction_id": "e10cc8d64204394cd35329a88dc4ab8f",
"timestamp": "2021-05-11 17:47:50",
"client_id": "[email protected]",
"ip": "172.69.34.31",
"level": "OK",
"request": {
"method": "POST",
"status_code": 200,
"status_name": "Ok",
"url": "/status/driver"
},
"bytes": 297,
"message": "Status authenticated successfully"
}......
我可以通過以下查詢通過時間戳(基于每日)獲取每個 request.url 的總數。
db.getCollection('collection').aggregate([
{
$match: {
client_id: { $regex : '^chae@'},
'request.url': { $regex : '^\/ocr'}}
},
{ '$group' :
{
'_id': { $substr: [ "$timestamp", 0, 10 ] },
count: { $sum: 1 }
}
},
{
'$sort':
{ 'count': -1}
}
])
然后我得到 request.url 的結果,其中包含 /^ocr/
_id | count
2021-10-01 | 10
2021-09-30 | 15
2021-09-29 | 11
....
好像沒問題。但是,如果我想獲得不同的 request.url,則必須發送另一個查詢。我可以通過一個查詢一次獲得所有不同 request.url 的結果嗎?
我想要的結果是這樣的。
_id | count(ocr) | count(status) | count(something else)
2021-10-01 | 10 | 20 | 56
2021-09-30 | 15 | 26 | 28
2021-09-29 | 11 | 87 | 466
我什至不知道在 mongodb 中是否有可能?請建議我。謝謝。
uj5u.com熱心網友回復:
您可以使用$facet獲得多個結果,如下所示:
如果您使用任何編程語言,您可以輕松地為查詢創建物件而不重復代碼。
db.collection.aggregate({
"$facet": {
"ocr": [
// your query here
],
"status": [
// your query using $regex : '^\/status'
],
"whatever":[
// your query using $regex : '^\/whatever'
]
}
})
示例在這里
uj5u.com熱心網友回復:
詢問
- group 也接受運算式,因此我們可以計算組值
- 這里我們有 2 個組鍵
- 他們的電子郵件以 chae 開頭,url 以 /ocr 開頭
- 他們的電子郵件以 chae 開頭,url 以 /status 開頭
- 我們分別總結這些
- 如果您在 上添加更多案例,
$switch您可以為許多不同的搜索執行此操作 - 如果您在撰寫查詢時不知道這些情況,則需要
{"$switch" ...}動態構造它,您可以使用回圈來完成,這很容易,回圈變數并創建它 - 如果您在這些欄位上有索引,則可以
$match在頂部添加一個,例如 allow only
(or (chae and /ocr) (chae and /status) ...)
還有一個$facet解決方案(facet = 每個欄位1個聚合)
- 如果索參考于 $match 、 $facet 或 $group 類似的性能(你做正則運算式匹配所以測驗索引使用),但 $facet 更簡單的查詢
- 如果不是索引,
$facet將對每個欄位進行 1 次集合掃描,所以選擇$group我認為的
測驗代碼在這里
aggregate(
[{"$group":
{"_id":
{"reg":
{"$switch":
{"branches":
[{"case":
{"$and":
[{"$regexMatch": {"input": "$client_id", "regex": "^chae@"}},
{"$regexMatch": {"input": "$request.url", "regex": "^/ocr"}}]},
"then": "chae-ocr"},
{"case":
{"$and":
[{"$regexMatch": {"input": "$client_id", "regex": "^chae@"}},
{"$regexMatch":
{"input": "$request.url", "regex": "^/status"}}]},
"then": "chae-status"}],
"default": "other"}},
"time": {"$substrCP": ["$timestamp", 0, 10]}},
"count": {"$sum": 1}}},
{"$project": {"_id": "$_id.time", "count": 1, "searched": "$_id.reg"}}])
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/338556.html
