mirror of
https://gitee.com/dotnetchina/SqlSugar.git
synced 2025-09-20 02:29:39 +08:00
Update mongodb
This commit is contained in:
@@ -55,43 +55,116 @@ namespace SqlSugar.MongoDb
|
|||||||
List<string> operations = new List<string>();
|
List<string> operations = new List<string>();
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
|
|
||||||
#region Where
|
#region Joins
|
||||||
foreach (var item in this.WhereInfos)
|
|
||||||
{
|
|
||||||
// 去除开头的 WHERE 或 AND(忽略大小写和空格)
|
|
||||||
string trimmed = item.TrimStart();
|
|
||||||
if (trimmed.StartsWith("WHERE", StringComparison.OrdinalIgnoreCase))
|
|
||||||
trimmed = trimmed.Substring(5).TrimStart();
|
|
||||||
else if (trimmed.StartsWith("AND", StringComparison.OrdinalIgnoreCase))
|
|
||||||
trimmed = trimmed.Substring(3).TrimStart();
|
|
||||||
if (MongoDbExpTools.IsFieldNameJson(trimmed))
|
|
||||||
{
|
|
||||||
var outerDoc = BsonDocument.Parse(trimmed);
|
|
||||||
trimmed = outerDoc[UtilConstants.FieldName].AsString;
|
|
||||||
operations.Add(trimmed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// item 是 JSON 格式字符串,直接包进 $match
|
|
||||||
operations.Add($"{{ \"$match\": {trimmed} }}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Page
|
ProcessWhereConditions(operations);
|
||||||
var skip = this.Skip;
|
|
||||||
var take = this.Take;
|
ProcessPagination(operations);
|
||||||
// 处理 skip 和 take
|
|
||||||
if (this.Skip.HasValue)
|
ProcessOrderByConditions(operations);
|
||||||
|
|
||||||
|
ProcessSelectConditions(operations);
|
||||||
|
|
||||||
|
ProcessGroupByConditions(operations);
|
||||||
|
|
||||||
|
sb.Append($"aggregate {this.GetTableNameString} ");
|
||||||
|
sb.Append("[");
|
||||||
|
sb.Append(string.Join(", ", operations));
|
||||||
|
sb.Append("]");
|
||||||
|
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessSelectConditions(List<string> operations)
|
||||||
|
{
|
||||||
|
#region Select
|
||||||
|
if (this.SelectValue is Expression expression)
|
||||||
{
|
{
|
||||||
operations.Add($"{{ \"$skip\": {this.Skip.Value} }}");
|
var dos = MongoNestedTranslator.Translate(expression, new MongoNestedTranslatorContext()
|
||||||
}
|
{
|
||||||
if (this.Take.HasValue)
|
context = this.Context,
|
||||||
{
|
resolveType = ResolveExpressType.SelectSingle,
|
||||||
operations.Add($"{{ \"$limit\": {this.Take.Value} }}");
|
queryBuilder = this
|
||||||
|
});
|
||||||
|
if (MongoDbExpTools.IsFieldNameJson(dos))
|
||||||
|
{
|
||||||
|
dos[UtilConstants.FieldName] = "$" + dos[UtilConstants.FieldName];
|
||||||
|
dos.Add(new BsonElement("_id", "0"));
|
||||||
|
}
|
||||||
|
else if (dos.ElementCount > 0 && dos.GetElement(0).Name.StartsWith("$"))
|
||||||
|
{
|
||||||
|
// 如果第一个key带有$,说明是个函数,外面套一层fieldName
|
||||||
|
var funcDoc = new BsonDocument(dos); // 复制一份
|
||||||
|
dos.Clear();
|
||||||
|
dos.Add(UtilConstants.FieldName, funcDoc);
|
||||||
|
dos.Add(new BsonElement("_id", "0"));
|
||||||
|
}
|
||||||
|
var json = dos.ToJson(UtilMethods.GetJsonWriterSettings());
|
||||||
|
operations.Add($"{{\"$project\": {json} }}");
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessGroupByConditions(List<string> operations)
|
||||||
|
{
|
||||||
|
#region GroupBy
|
||||||
|
if (this.GroupByValue.HasValue())
|
||||||
|
{
|
||||||
|
var regex = new Regex($@"\(\{UtilConstants.ReplaceCommaKey}\((.*?)\)\{UtilConstants.ReplaceCommaKey}\)",
|
||||||
|
RegexOptions.Compiled);
|
||||||
|
|
||||||
|
var matches = regex.Matches(this.GroupByValue);
|
||||||
|
var selectItems = new List<string>();
|
||||||
|
foreach (Match match in matches)
|
||||||
|
{
|
||||||
|
var selectItem = match.Groups[1].Value;
|
||||||
|
selectItems.Add(selectItem);
|
||||||
|
}
|
||||||
|
var jsonPart = "[" + Regex.Split(this.GroupByValue, UtilConstants.ReplaceCommaKey)
|
||||||
|
.First()
|
||||||
|
.TrimEnd('(')
|
||||||
|
.Replace("GROUP BY ", "") + "]";
|
||||||
|
var fieldNames = new List<string>();
|
||||||
|
var bsonArray = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonArray>(jsonPart);
|
||||||
|
foreach (BsonDocument bson in bsonArray)
|
||||||
|
{
|
||||||
|
if (bson.Contains(UtilConstants.FieldName))
|
||||||
|
{
|
||||||
|
var field = bson[UtilConstants.FieldName].AsString;
|
||||||
|
operations[operations.Count - 1] = operations[operations.Count - 1].Replace($"\"${field}\"", $"\"$_id.{field}\"");
|
||||||
|
fieldNames.Add(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 构造 _id 部分:支持多字段形式
|
||||||
|
var groupId = new BsonDocument();
|
||||||
|
foreach (var field in fieldNames)
|
||||||
|
{
|
||||||
|
groupId.Add(field, $"${field}");
|
||||||
|
}
|
||||||
|
|
||||||
|
var groupDoc = new BsonDocument("$group", new BsonDocument
|
||||||
|
{
|
||||||
|
{ "_id", groupId }
|
||||||
|
});
|
||||||
|
|
||||||
|
// 解析 selectJsonItems(每个是 BsonDocument 字符串)
|
||||||
|
var groupFields = groupDoc["$group"].AsBsonDocument;
|
||||||
|
foreach (var json in selectItems)
|
||||||
|
{
|
||||||
|
var doc = BsonDocument.Parse(json);
|
||||||
|
foreach (var element in doc)
|
||||||
|
{
|
||||||
|
groupFields.Add(element.Name, element.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
operations.Insert(operations.Count - 1, groupDoc.ToJson(UtilMethods.GetJsonWriterSettings()));
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessOrderByConditions(List<string> operations)
|
||||||
|
{
|
||||||
#region OrderBy
|
#region OrderBy
|
||||||
var order = this.GetOrderByString;
|
var order = this.GetOrderByString;
|
||||||
var orderByString = this.GetOrderByString?.Trim();
|
var orderByString = this.GetOrderByString?.Trim();
|
||||||
@@ -126,94 +199,51 @@ namespace SqlSugar.MongoDb
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Select
|
|
||||||
if (this.SelectValue is Expression expression)
|
|
||||||
{
|
|
||||||
var dos=MongoNestedTranslator.Translate(expression, new MongoNestedTranslatorContext() {
|
|
||||||
context = this.Context,
|
|
||||||
resolveType=ResolveExpressType.SelectSingle,
|
|
||||||
queryBuilder=this
|
|
||||||
});
|
|
||||||
if (MongoDbExpTools.IsFieldNameJson(dos))
|
|
||||||
{
|
|
||||||
dos[UtilConstants.FieldName] = "$"+ dos[UtilConstants.FieldName];
|
|
||||||
dos.Add(new BsonElement("_id", "0"));
|
|
||||||
}
|
|
||||||
else if (dos.ElementCount > 0 && dos.GetElement(0).Name.StartsWith("$"))
|
|
||||||
{
|
|
||||||
// 如果第一个key带有$,说明是个函数,外面套一层fieldName
|
|
||||||
var funcDoc = new BsonDocument(dos); // 复制一份
|
|
||||||
dos.Clear();
|
|
||||||
dos.Add(UtilConstants.FieldName, funcDoc);
|
|
||||||
dos.Add(new BsonElement("_id", "0"));
|
|
||||||
}
|
|
||||||
var json = dos.ToJson(UtilMethods.GetJsonWriterSettings());
|
|
||||||
operations.Add($"{{\"$project\": {json} }}");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region GroupBy
|
|
||||||
if (this.GroupByValue.HasValue())
|
|
||||||
{
|
|
||||||
var regex = new Regex($@"\(\{UtilConstants.ReplaceCommaKey}\((.*?)\)\{UtilConstants.ReplaceCommaKey}\)",
|
|
||||||
RegexOptions.Compiled);
|
|
||||||
|
|
||||||
var matches = regex.Matches(this.GroupByValue);
|
|
||||||
var selectItems = new List<string>();
|
|
||||||
foreach (Match match in matches)
|
|
||||||
{
|
|
||||||
var selectItem = match.Groups[1].Value;
|
|
||||||
selectItems.Add(selectItem);
|
|
||||||
}
|
|
||||||
var jsonPart = "["+Regex.Split(this.GroupByValue, UtilConstants.ReplaceCommaKey)
|
|
||||||
.First()
|
|
||||||
.TrimEnd('(')
|
|
||||||
.Replace("GROUP BY ", "")+"]";
|
|
||||||
var fieldNames = new List<string>();
|
|
||||||
var bsonArray = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonArray>(jsonPart);
|
|
||||||
foreach (BsonDocument bson in bsonArray)
|
|
||||||
{
|
|
||||||
if (bson.Contains(UtilConstants.FieldName))
|
|
||||||
{
|
|
||||||
var field = bson[UtilConstants.FieldName].AsString;
|
|
||||||
operations[operations.Count - 1] = operations[operations.Count - 1].Replace($"\"${field}\"", $"\"$_id.{field}\"");
|
|
||||||
fieldNames.Add(field);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 构造 _id 部分:支持多字段形式
|
|
||||||
var groupId = new BsonDocument();
|
|
||||||
foreach (var field in fieldNames)
|
|
||||||
{
|
|
||||||
groupId.Add(field, $"${field}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var groupDoc = new BsonDocument("$group", new BsonDocument
|
|
||||||
{
|
|
||||||
{ "_id", groupId }
|
|
||||||
});
|
|
||||||
|
|
||||||
// 解析 selectJsonItems(每个是 BsonDocument 字符串)
|
|
||||||
var groupFields = groupDoc["$group"].AsBsonDocument;
|
|
||||||
foreach (var json in selectItems)
|
|
||||||
{
|
|
||||||
var doc = BsonDocument.Parse(json);
|
|
||||||
foreach (var element in doc)
|
|
||||||
{
|
|
||||||
groupFields.Add(element.Name, element.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
operations.Insert(operations.Count-1, groupDoc.ToJson(UtilMethods.GetJsonWriterSettings()));
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
sb.Append($"aggregate {this.GetTableNameString} ");
|
|
||||||
sb.Append("[");
|
|
||||||
sb.Append(string.Join(", ", operations));
|
|
||||||
sb.Append("]");
|
|
||||||
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ProcessPagination(List<string> operations)
|
||||||
|
{
|
||||||
|
#region Page
|
||||||
|
var skip = this.Skip;
|
||||||
|
var take = this.Take;
|
||||||
|
// 处理 skip 和 take
|
||||||
|
if (this.Skip.HasValue)
|
||||||
|
{
|
||||||
|
operations.Add($"{{ \"$skip\": {this.Skip.Value} }}");
|
||||||
|
}
|
||||||
|
if (this.Take.HasValue)
|
||||||
|
{
|
||||||
|
operations.Add($"{{ \"$limit\": {this.Take.Value} }}");
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ProcessWhereConditions(List<string> operations)
|
||||||
|
{
|
||||||
|
#region Where
|
||||||
|
foreach (var item in this.WhereInfos)
|
||||||
|
{
|
||||||
|
// 去除开头的 WHERE 或 AND(忽略大小写和空格)
|
||||||
|
string trimmed = item.TrimStart();
|
||||||
|
if (trimmed.StartsWith("WHERE", StringComparison.OrdinalIgnoreCase))
|
||||||
|
trimmed = trimmed.Substring(5).TrimStart();
|
||||||
|
else if (trimmed.StartsWith("AND", StringComparison.OrdinalIgnoreCase))
|
||||||
|
trimmed = trimmed.Substring(3).TrimStart();
|
||||||
|
if (MongoDbExpTools.IsFieldNameJson(trimmed))
|
||||||
|
{
|
||||||
|
var outerDoc = BsonDocument.Parse(trimmed);
|
||||||
|
trimmed = outerDoc[UtilConstants.FieldName].AsString;
|
||||||
|
operations.Add(trimmed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// item 是 JSON 格式字符串,直接包进 $match
|
||||||
|
operations.Add($"{{ \"$match\": {trimmed} }}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToCountSql(string sql)
|
public override string ToCountSql(string sql)
|
||||||
{
|
{
|
||||||
sql=sql.TrimEnd(']');
|
sql=sql.TrimEnd(']');
|
||||||
|
Reference in New Issue
Block a user