ASP.NET Core调试时记录MongoDB查询语句的实现方法
在ASP.NET Core中记录MongoDB LINQ查询语句(控制台/日志)
方法一:启用MongoDB驱动内置日志
直接通过ASP.NET Core配置开启MongoDB命令级日志,驱动会自动输出LINQ转换后的原生查询语句:
- 在
appsettings.json中添加日志级别配置:
{ "Logging": { "LogLevel": { "Default": "Information", "Microsoft.AspNetCore": "Warning", "MongoDB.Driver.Core.Events.Command": "Information" } } }
- 启动应用后,所有MongoDB执行的命令(包括LINQ生成的查询)都会输出到控制台或配置的日志文件中。
方法二:手动查看单个LINQ查询的原生语句
针对特定LINQ查询,可直接转换为BsonDocument查看对应的MongoDB查询:
// 假设collection是你的IMongoCollection<YourEntity>实例 var linqQuery = collection.AsQueryable<YourEntity>() .Where(x => x.Age > 18) .OrderBy(x => x.CreateTime); // 转换为MongoDB原生查询文档 var mongoQuery = linqQuery.ToBsonDocument(); // 输出到控制台 Console.WriteLine($"MongoDB查询语句:\n{mongoQuery}"); // 或者写入日志(需注入ILogger) _logger.LogInformation("MongoDB查询语句:\n{Query}", mongoQuery);
方法三:全局拦截所有MongoDB命令(推荐全局监控)
实现MongoDB驱动的ICommandInterceptor接口,全局拦截所有执行命令,记录查询语句和执行耗时:
1. 实现拦截器类
using MongoDB.Driver.Core.Events; using Microsoft.Extensions.Logging; public class MongoCommandLogger : ICommandInterceptor { private readonly ILogger<MongoCommandLogger> _logger; public MongoCommandLogger(ILogger<MongoCommandLogger> logger) { _logger = logger; } public void Executing<TCommand>(CommandEvent<TCommand> @event) where TCommand : Command { // 将命令序列化为格式化JSON var commandJson = @event.Command.ToJson(new JsonWriterSettings { Indent = true }); _logger.LogInformation("准备执行MongoDB命令:\n{Command}", commandJson); } public void Executed<TCommand>(CommandEvent<TCommand> @event) where TCommand : Command { // 记录执行耗时 var elapsedMs = @event.Duration.TotalMilliseconds; _logger.LogInformation("MongoDB命令执行完成,耗时: {ElapsedMs:F2}ms", elapsedMs); } }
2. 注册拦截器到MongoClient
在Program.cs中注册MongoClient时添加拦截器:
var builder = WebApplication.CreateBuilder(args); // 注册拦截器 builder.Services.AddSingleton<MongoCommandLogger>(); // 注册MongoClient并添加拦截器 builder.Services.AddSingleton<IMongoClient>(sp => { var connectionString = builder.Configuration.GetConnectionString("MongoDB"); var settings = MongoClientSettings.FromConnectionString(connectionString); var loggerInterceptor = sp.GetRequiredService<MongoCommandLogger>(); settings.ClusterConfigurator = cb => cb.Subscribe(loggerInterceptor); return new MongoClient(settings); });
性能排查建议
拿到记录的查询语句后,可在MongoDB Shell或Compass中执行explain()分析执行计划:
db.yourCollection.find({ "Age": { "$gt": 18 } }).explain("executionStats")
重点关注:
executionStats.executionTimeMillis:查询执行耗时executionStats.totalDocsExamined:扫描的文档数量(远大于返回结果数时,说明缺少合适索引)executionStats.executionStages.stage:执行阶段,IXSCAN表示使用索引,COLLSCAN表示全表扫描
内容的提问来源于stack exchange,提问作者Allani Saikumar
相关产品推荐
相关产品推荐

