Update mongodb

This commit is contained in:
sunkaixuan 2025-06-11 18:41:47 +08:00
parent 0e9cb3176b
commit b3da93082b
5 changed files with 91 additions and 346 deletions

View File

@ -118,13 +118,13 @@ namespace MongoDbTest
Name2 = "b"+it.Name
}).ToDataTable();
//var list13 = db.Queryable<OrderInfo>()
// .GroupBy(it=>it.Name)
// .Select(it => new
// {
// Id = it.Name,
// Name =SqlFunc.AggregateMax(it.Id)
// }).ToList();
var list13 = db.Queryable<OrderInfo>()
.GroupBy(it => it.Name)
.Select(it => new
{
Id = it.Name,
MyCount = SqlFunc.AggregateCount(it.Id)
}).ToList();
//测试生成SQL性能
TestSqlBuilder(db);
}

View File

@ -7,6 +7,7 @@ namespace SqlSugar.MongoDb
public class MongoNestedTranslatorContext
{
public ResolveExpressType resolveType { get; internal set; }
public SqlSugarProvider context { get; internal set; }
public SqlSugarProvider context { get; internal set; }
public QueryBuilder queryBuilder { get; internal set; }
}
}

View File

@ -28,13 +28,14 @@ namespace SqlSugar.MongoDb
BsonValue result = null;
if (typeof(IDbMethods).GetMethods().Any(it => it.Name == name))
{
var context = new MongoDbMethod();
var context = new MongoDbMethod() { context=this._context};
MethodCallExpressionModel model = new MethodCallExpressionModel();
var args= methodCallExpression.Arguments;
var args= methodCallExpression.Arguments;
model.Args = new List<MethodCallExpressionArgs>();
foreach (var item in args)
{
//开发中
}
model.Args.Add(new MethodCallExpressionArgs() { MemberValue = item });
}
var funcString= context.GetType().GetMethod(name).Invoke(context, new object[] { model });
result = BsonValue.Create(funcString);
}

View File

@ -13,6 +13,7 @@ namespace SqlSugar.MongoDb
var context = new MongoNestedTranslatorContext();
context.resolveType = resolveType;
context.context = this.SugarContext.Context;
context.queryBuilder = this.SugarContext.QueryBuilder;
var sql=MongoNestedTranslator.Translate(expression, context);
var shellString = sql.ToJson(new JsonWriterSettings
{
@ -154,356 +155,97 @@ namespace SqlSugar.MongoDb
}
public class MongoDbMethod : DefaultDbMethod, IDbMethods
{
public override string GetDateString(string dateValue, string formatString)
public MongoNestedTranslatorContext context { get; set; }
public override string AggregateCount(MethodCallExpressionModel model)
{
if (!(formatString?.Contains("24") == true))
var index = context.queryBuilder.LambdaExpressions.Index;
var name = "count" + index;
var item=model.Args.First().MemberValue;
BsonValue arg = new ExpressionVisitor(context).Visit(item as Expression);
if (arg is BsonString str && !str.AsString.StartsWith("$"))
{
formatString = formatString.Replace("HH", "hh24");
if (!(formatString?.Contains("24") == true))
arg = "$" + str.AsString;
}
var countExpression = new BsonDocument(name, new BsonDocument("$sum",
new BsonDocument("$cond", new BsonArray
{
formatString = formatString.Replace("hh", "hh24");
}
}
formatString = formatString.Replace("mm", "mi");
return $"to_char({dateValue},'{formatString}') ";
new BsonDocument("$ifNull", new BsonArray { arg, false }),
1,
0
})
));
var result= countExpression.ToJson(SqlSugar.MongoDb.UtilMethods.GetJsonWriterSettings());
context.queryBuilder.GroupByValue += $"({UtilConstants.ReplaceCommaKey}({result}){UtilConstants.ReplaceCommaKey})";
context.queryBuilder.LambdaExpressions.Index++;
return name;
}
public override string CharIndex(MethodCallExpressionModel model)
public override string AggregateMax(MethodCallExpressionModel model)
{
return string.Format(" (strpos ({1},{0})-1)", model.Args[0].MemberName, model.Args[1].MemberName);
}
public override string TrueValue()
{
return "true";
}
public override string FalseValue()
{
return "false";
}
public override string DateDiff(MethodCallExpressionModel model)
{
var parameter = (DateType)(Enum.Parse(typeof(DateType), model.Args[0].MemberValue.ObjToString()));
var begin = model.Args[1].MemberName;
var end = model.Args[2].MemberName;
switch (parameter)
var index = context.queryBuilder.LambdaExpressions.Index;
var name = "max" + index;
var item = model.Args.First().MemberValue;
BsonValue arg = new ExpressionVisitor(context).Visit(item as Expression);
if (arg is BsonString str && !str.AsString.StartsWith("$"))
{
case DateType.Year:
return $" ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) )";
case DateType.Month:
return $" ( ( DATE_PART('Year', {end} ) - DATE_PART('Year', {begin}) ) * 12 + (DATE_PART('month', {end}) - DATE_PART('month', {begin})) )";
case DateType.Day:
return $" ( DATE_PART('day', {end} - {begin}) )";
case DateType.Hour:
return $" ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) )";
case DateType.Minute:
return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) )";
case DateType.Second:
return $" ( ( ( DATE_PART('day', {end} - {begin}) ) * 24 + DATE_PART('hour', {end} - {begin} ) ) * 60 + DATE_PART('minute', {end} - {begin} ) ) * 60 + DATE_PART('second', {end} - {begin} )";
case DateType.Millisecond:
break;
default:
break;
arg = "$" + str.AsString;
}
throw new Exception(parameter + " datediff no support");
var maxExpression = new BsonDocument(name, new BsonDocument("$max", arg));
var result = maxExpression.ToJson(SqlSugar.MongoDb.UtilMethods.GetJsonWriterSettings());
context.queryBuilder.GroupByValue += $"({UtilConstants.ReplaceCommaKey}({result}){UtilConstants.ReplaceCommaKey})";
context.queryBuilder.LambdaExpressions.Index++;
return name;
}
public override string IIF(MethodCallExpressionModel model)
public override string AggregateMin(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
if (parameter.Type == UtilConstants.BoolType)
var index = context.queryBuilder.LambdaExpressions.Index;
var name = "min" + index;
var item = model.Args.First().MemberValue;
BsonValue arg = new ExpressionVisitor(context).Visit(item as Expression);
if (arg is BsonString str && !str.AsString.StartsWith("$"))
{
parameter.MemberName = parameter.MemberName.ToString().Replace("=1", "=true");
parameter2.MemberName = false;
parameter3.MemberName = true;
arg = "$" + str.AsString;
}
return string.Format("( CASE WHEN {0} THEN {1} ELSE {2} END )", parameter.MemberName, parameter2.MemberName, parameter3.MemberName);
var minExpression = new BsonDocument(name, new BsonDocument("$min", arg));
var result = minExpression.ToJson(SqlSugar.MongoDb.UtilMethods.GetJsonWriterSettings());
context.queryBuilder.GroupByValue += $"({UtilConstants.ReplaceCommaKey}({result}){UtilConstants.ReplaceCommaKey})";
context.queryBuilder.LambdaExpressions.Index++;
return name;
}
public override string DateValue(MethodCallExpressionModel model)
public override string AggregateAvg(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var format = "dd";
if (parameter2.MemberValue.ObjToString() == DateType.Year.ToString())
var index = context.queryBuilder.LambdaExpressions.Index;
var name = "avg" + index;
var item = model.Args.First().MemberValue;
BsonValue arg = new ExpressionVisitor(context).Visit(item as Expression);
if (arg is BsonString str && !str.AsString.StartsWith("$"))
{
format = "yyyy";
arg = "$" + str.AsString;
}
if (parameter2.MemberValue.ObjToString() == DateType.Month.ToString())
var avgExpression = new BsonDocument(name, new BsonDocument("$avg", arg));
var result = avgExpression.ToJson(SqlSugar.MongoDb.UtilMethods.GetJsonWriterSettings());
context.queryBuilder.GroupByValue += $"({UtilConstants.ReplaceCommaKey}({result}){UtilConstants.ReplaceCommaKey})";
context.queryBuilder.LambdaExpressions.Index++;
return name;
}
public override string AggregateSum(MethodCallExpressionModel model)
{
var index = context.queryBuilder.LambdaExpressions.Index;
var name = "sum" + index;
var item = model.Args.First().MemberValue;
BsonValue arg = new ExpressionVisitor(context).Visit(item as Expression);
if (arg is BsonString str && !str.AsString.StartsWith("$"))
{
format = "MM";
}
if (parameter2.MemberValue.ObjToString() == DateType.Day.ToString())
{
format = "dd";
}
if (parameter2.MemberValue.ObjToString() == DateType.Hour.ToString())
{
format = "hh";
}
if (parameter2.MemberValue.ObjToString() == DateType.Minute.ToString())
{
format = "mi";
}
if (parameter2.MemberValue.ObjToString() == DateType.Second.ToString())
{
format = "ss";
}
if (parameter2.MemberValue.ObjToString() == DateType.Millisecond.ToString())
{
format = "ms";
}
if (parameter2.MemberValue.ObjToString() == DateType.Weekday.ToString())
{
return $" extract(DOW FROM cast({parameter.MemberName} as TIMESTAMP)) ";
}
return string.Format(" cast( to_char({1},'{0}')as integer ) ", format, parameter.MemberName);
}
public override string Contains(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like concat('%',{1},'%')) ", parameter.MemberName, parameter2.MemberName );
}
public override string StartsWith(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like concat({1},'%')) ", parameter.MemberName, parameter2.MemberName);
}
public override string EndsWith(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} like concat('%',{1}))", parameter.MemberName,parameter2.MemberName);
}
public override string DateIsSameDay(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ( to_char({0},'yyyy-MM-dd')=to_char({1},'yyyy-MM-dd') ) ", parameter.MemberName, parameter2.MemberName); ;
}
public override string HasValue(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format("( {0} IS NOT NULL )", parameter.MemberName);
}
public override string DateIsSameByType(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
DateType dateType =(DateType)parameter3.MemberValue;
var format = "yyyy-MM-dd";
if (dateType == DateType.Quarter)
{
return string.Format(" (date_trunc('quarter',{0})=date_trunc('quarter',{1}) ) ", parameter.MemberName, parameter2.MemberName,format);
}
switch (dateType)
{
case DateType.Year:
format = "yyyy";
break;
case DateType.Month:
format = "yyyy-MM";
break;
case DateType.Day:
break;
case DateType.Hour:
format = "yyyy-MM-dd HH";
break;
case DateType.Second:
format = "yyyy-MM-dd HH:mm:ss";
break;
case DateType.Minute:
format = "yyyy-MM-dd HH:mm";
break;
case DateType.Millisecond:
format = "yyyy-MM-dd HH:mm.ms";
break;
default:
break;
}
return string.Format(" ( to_char({0},'{2}')=to_char({1},'{2}') ) ", parameter.MemberName, parameter2.MemberName, format);
}
public override string ToDate(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS timestamp)", parameter.MemberName);
}
public override string DateAddByType(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
var parameter3 = model.Args[2];
return string.Format(" ({1} + ({2}||'{0}')::INTERVAL) ", parameter3.MemberValue, parameter.MemberName, parameter2.MemberName);
}
public override string DateAddDay(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter2 = model.Args[1];
return string.Format(" ({0} + ({1}||'day')::INTERVAL) ", parameter.MemberName, parameter2.MemberName);
}
public override string ToInt32(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS INT4)", parameter.MemberName);
}
public override string ToInt64(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS INT8)", parameter.MemberName);
}
public override string ToString(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS VARCHAR)", parameter.MemberName);
}
public override string ToGuid(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS UUID)", parameter.MemberName);
}
public override string ToDouble(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName);
}
public override string ToBool(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS boolean)", parameter.MemberName);
}
public override string ToDecimal(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" CAST({0} AS DECIMAL(18,4))", parameter.MemberName);
}
public override string Length(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
return string.Format(" LENGTH({0})", parameter.MemberName);
}
public override string MergeString(params string[] strings)
{
return " concat("+string.Join(",", strings).Replace("+", "") + ") ";
}
public override string IsNull(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter1 = model.Args[1];
return string.Format("(CASE WHEN {0} IS NULL THEN {1} ELSE {0} END)", parameter.MemberName, parameter1.MemberName);
}
public override string GetDate()
{
return " current_timestamp ";
}
public override string GetRandom()
{
return "RANDOM()";
}
public override string EqualTrue(string fieldName)
{
return "( " + fieldName + "=true )";
}
public override string JsonField(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter1 = model.Args[1];
//var parameter2 = model.Args[2];
//var parameter3= model.Args[3];
var result= GetJson(parameter.MemberName, parameter1.MemberName, model.Args.Count()==2);
if (model.Args.Count > 2)
{
result = GetJson(result, model.Args[2].MemberName, model.Args.Count() == 3);
}
if (model.Args.Count > 3)
{
result = GetJson(result, model.Args[3].MemberName, model.Args.Count() == 4);
}
if (model.Args.Count > 4)
{
result = GetJson(result, model.Args[4].MemberName, model.Args.Count() == 5);
}
if (model.Args.Count > 5)
{
result = GetJson(result, model.Args[5].MemberName, model.Args.Count() == 6);
}
return result;
}
public override string JsonContainsFieldName(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
var parameter1 = model.Args[1];
return $"({parameter.MemberName}::jsonb ?{parameter1.MemberName})";
}
private string GetJson(object memberName1, object memberName2,bool isLast)
{
if (isLast)
{
return $"({memberName1}::json->>{memberName2})";
}
else
{
return $"({memberName1}->{memberName2})";
}
}
public override string JsonArrayLength(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
//var parameter1 = model.Args[1];
return $" json_array_length({parameter.MemberName}::json) ";
}
public override string JsonParse(MethodCallExpressionModel model)
{
var parameter = model.Args[0];
//var parameter1 = model.Args[1];
return $" ({parameter.MemberName}::json) ";
}
public override string JsonArrayAny(MethodCallExpressionModel model)
{
if (SqlSugar.UtilMethods.IsNumber(model.Args[1].MemberValue.GetType().Name))
{
return $" {model.Args[0].MemberName}::jsonb @> '[{model.Args[1].MemberValue.ObjToStringNoTrim().ToSqlFilter()}]'::jsonb";
}
else
{
return $" {model.Args[0].MemberName}::jsonb @> '[\"{model.Args[1].MemberValue}\"]'::jsonb";
}
}
public override string JsonListObjectAny(MethodCallExpressionModel model)
{
if (SqlSugar.UtilMethods.IsNumber(model.Args[2].MemberValue.GetType().Name))
{
return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":{model.Args[2].MemberValue}}}]'::jsonb";
}
else
{
return $" {model.Args[0].MemberName}::jsonb @> '[{{\"{model.Args[1].MemberValue}\":\"{model.Args[2].MemberValue.ObjToStringNoTrim().ToSqlFilter()}\"}}]'::jsonb";
arg = "$" + str.AsString;
}
var sumExpression = new BsonDocument(name, new BsonDocument("$sum", arg));
var result = sumExpression.ToJson(SqlSugar.MongoDb.UtilMethods.GetJsonWriterSettings());
context.queryBuilder.GroupByValue += $"({UtilConstants.ReplaceCommaKey}({result}){UtilConstants.ReplaceCommaKey})";
context.queryBuilder.LambdaExpressions.Index++;
return name;
}
}
}

View File

@ -121,7 +121,8 @@ namespace SqlSugar.MongoDb
{
var dos=MongoNestedTranslator.Translate(expression, new MongoNestedTranslatorContext() {
context = this.Context,
resolveType=ResolveExpressType.SelectSingle
resolveType=ResolveExpressType.SelectSingle,
queryBuilder=this
});
var json = dos.ToJson(UtilMethods.GetJsonWriterSettings());
operations.Add($"{{\"$project\": {json} }}");