564 lines
22 KiB
C#
564 lines
22 KiB
C#
using System.Linq.Expressions;
|
|
using MongoDB.Bson;
|
|
using MongoDB.Driver;
|
|
using UGQDataAccess.Repository.Models;
|
|
using UGQDatabase.Models;
|
|
|
|
namespace UGQDataAccess.Repository.Query;
|
|
|
|
public static class QuestContentQuery
|
|
{
|
|
public class QuestBoardQueryJoin : QuestContentEntity
|
|
{
|
|
public IEnumerable<LikeEntity> Likes { get; set; } = null!;
|
|
public int LikeCount { get; set; } = 0;
|
|
public IEnumerable<BookmarkEntity> Bookmarks { get; set; } = null!;
|
|
public int BookmarkCount { get; set; } = 0;
|
|
|
|
public List<QuestAcceptedEntity> QuestAccepteds { get; set; } = null!;
|
|
public int QuestAcceptedCount { get; set; } = 0;
|
|
|
|
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
|
public int QuestCompletedCount { get; set; } = 0;
|
|
}
|
|
|
|
public class QuestSummariesQueryJoin : QuestContentEntity
|
|
{
|
|
public IEnumerable<LikeEntity> Likes { get; set; } = null!;
|
|
public int LikeCount { get; set; } = 0;
|
|
public IEnumerable<BookmarkEntity> Bookmarks { get; set; } = null!;
|
|
public int BookmarkCount { get; set; } = 0;
|
|
|
|
public List<QuestAcceptedEntity> QuestAccepteds { get; set; } = null!;
|
|
public int QuestAcceptedCount { get; set; } = 0;
|
|
|
|
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
|
public int QuestCompletedCount { get; set; } = 0;
|
|
|
|
public List<QuestAcceptedEntity> QuestAborteds { get; set; } = null!;
|
|
public int QuestAbortedCount { get; set; } = 0;
|
|
|
|
public List<ReportEntity> Reports { get; set; } = null!;
|
|
public int ReporCount { get; set; } = 0;
|
|
|
|
public List<CreatorPointHistoryEntity> ProfitHistories { get; set; } = null!;
|
|
public double TotalProfit { get; set; } = 0;
|
|
}
|
|
|
|
public class QuestProfitStatsQueryJoin : QuestContentEntity
|
|
{
|
|
public List<QuestAcceptedEntity> QuestCompleteds { get; set; } = null!;
|
|
public int QuestCompletedCount { get; set; } = 0;
|
|
|
|
public List<CreatorPointHistoryEntity> ProfitHistories { get; set; } = null!;
|
|
public double TotalProfit { get; set; } = 0;
|
|
}
|
|
|
|
public class QuestAcceptedLookup : QuestAcceptedEntity
|
|
{
|
|
}
|
|
|
|
public static Expression<Func<QuestBoardQueryJoin, QuestBoardItemResult>> QuestBoardItemResultProjection =
|
|
x => new QuestBoardItemResult
|
|
{
|
|
QuestId = x.QuestId,
|
|
Revision = x.Revision,
|
|
Author = x.Author,
|
|
Title = x.Title,
|
|
Languages = x.Langs,
|
|
Cost = x.Cost,
|
|
GradeType = x.GradeType,
|
|
TitleImagePath = x.TitleImagePath,
|
|
BannerImagePath = x.BannerImagePath,
|
|
UpdatedAt = x.UpdatedAt,
|
|
LikeCount = x.LikeCount,
|
|
BookmarkCount = x.BookmarkCount,
|
|
};
|
|
|
|
|
|
public static Expression<Func<QuestSummariesQueryJoin, SummaryItemResult>> SummaryItemResultProjection =
|
|
x => new SummaryItemResult
|
|
{
|
|
QuestContentId = x.Id.ToString(),
|
|
QuestId = x.QuestId,
|
|
Revision = x.Revision,
|
|
BeaconId = x.BeaconId,
|
|
|
|
UserGuid = x.UserGuid,
|
|
Author = x.Author,
|
|
|
|
UgcBeaconGuid = x.UgcBeaconGuid,
|
|
UgcBeaconNickname = x.UgcBeaconNickname,
|
|
|
|
GradeType = x.GradeType,
|
|
|
|
Title = x.Title,
|
|
Languages = x.Langs,
|
|
Description = x.Description,
|
|
Cost = x.Cost,
|
|
TitleImagePath = x.TitleImagePath,
|
|
BannerImagePath = x.BannerImagePath,
|
|
State = x.State,
|
|
UpdatedAt = x.UpdatedAt,
|
|
CreatedAt = x.CreatedAt,
|
|
|
|
AcceptedCount = x.QuestAcceptedCount,
|
|
CompletedCount = x.QuestCompletedCount,
|
|
LikeCount = x.LikeCount,
|
|
BookmarkCount = x.BookmarkCount,
|
|
ReportCount = x.ReporCount,
|
|
|
|
TotalProfit = x.TotalProfit,
|
|
Savelanguage = x.Savelanguage,
|
|
};
|
|
|
|
public static Expression<Func<QuestProfitStatsQueryJoin, QuestProfitStatsItemResult>> QuestProfitStatsResultProjection =
|
|
x => new QuestProfitStatsItemResult
|
|
{
|
|
QuestContentId = x.Id.ToString(),
|
|
QuestId = x.QuestId,
|
|
Revision = x.Revision,
|
|
|
|
Title = x.Title,
|
|
Languages = x.Langs,
|
|
TitleImagePath = x.TitleImagePath,
|
|
BannerImagePath = x.BannerImagePath,
|
|
|
|
CompletedCount = x.QuestCompletedCount,
|
|
TotalProfit = x.TotalProfit,
|
|
};
|
|
|
|
|
|
static List<UgqGradeType> getGradeTypes(UgqUICategoryGradeType gradeType)
|
|
{
|
|
switch (gradeType)
|
|
{
|
|
case UgqUICategoryGradeType.Amateur:
|
|
return [UgqGradeType.Amature];
|
|
case UgqUICategoryGradeType.RisingStar:
|
|
return [UgqGradeType.RisingStar];
|
|
case UgqUICategoryGradeType.Master:
|
|
return [UgqGradeType.Master1, UgqGradeType.Master2, UgqGradeType.Master3];
|
|
}
|
|
|
|
return [];
|
|
}
|
|
|
|
static async Task<List<long>> getBookmarks(IMongoCollection<BookmarkEntity> bookmarkCollection, string userGuid)
|
|
{
|
|
var filterBuilder = Builders<BookmarkEntity>.Filter;
|
|
var filter = filterBuilder.Eq(x => x.UserGuid, userGuid);
|
|
|
|
var list = await bookmarkCollection.Find(filter).ToListAsync();
|
|
|
|
return list.Select(x => x.QuestId).ToList();
|
|
}
|
|
|
|
static async Task<List<int>> searchNpcs(IMongoCollection<NpcNameEntity> npcNameCollection, string searchText)
|
|
{
|
|
var filterBuilder = Builders<NpcNameEntity>.Filter;
|
|
var filter = filterBuilder.Empty;
|
|
|
|
if (string.IsNullOrEmpty(searchText) == false)
|
|
{
|
|
filter &= (filterBuilder.Regex(x => x.NpcName.Kr, searchText) |
|
|
filterBuilder.Regex(x => x.NpcName.En, searchText) |
|
|
filterBuilder.Regex(x => x.NpcName.Jp, searchText));
|
|
}
|
|
|
|
var list = await npcNameCollection.Find(filter).ToListAsync();
|
|
|
|
return list.Select(x => x.NpcId).ToList();
|
|
}
|
|
|
|
static FilterDefinition<QuestContentEntity> searchTitle(FilterDefinitionBuilder<QuestContentEntity> filterBuilder, string searchText)
|
|
{
|
|
return filterBuilder.Regex(x => x.Title.Kr, searchText) |
|
|
filterBuilder.Regex(x => x.Title.En, searchText) |
|
|
filterBuilder.Regex(x => x.Title.Jp, searchText);
|
|
}
|
|
|
|
public static async Task<FilterDefinition<QuestContentEntity>> summariesFilter(string? userGuid,
|
|
UgqSearchType searchType, string? searchText, QuestContentState state,
|
|
IMongoCollection<AccountEntity> accountCollection,
|
|
IMongoCollection<NpcNameEntity> npcNameCollection)
|
|
{
|
|
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
|
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
|
|
|
if (state != QuestContentState.None)
|
|
{
|
|
if(state == QuestContentState.Uncomplate ||
|
|
state == QuestContentState.Editable)
|
|
{
|
|
var UncomplateOrFilter = filterBuilder.Eq(x => x.State, QuestContentState.Uncomplate);
|
|
var EditableOrFilter = filterBuilder.Eq(x => x.State, QuestContentState.Editable);
|
|
filter &= filterBuilder.Or(UncomplateOrFilter, EditableOrFilter);
|
|
}
|
|
else
|
|
{
|
|
filter &= filterBuilder.Eq(x => x.State, state);
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(userGuid) == false)
|
|
filter &= filterBuilder.Eq(x => x.UserGuid, userGuid);
|
|
|
|
if (string.IsNullOrEmpty(searchText) == false)
|
|
{
|
|
switch (searchType)
|
|
{
|
|
case UgqSearchType.Title:
|
|
filter &= searchTitle(filterBuilder, searchText);
|
|
break;
|
|
case UgqSearchType.Beacon:
|
|
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
|
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
|
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return filter;
|
|
}
|
|
|
|
public static async Task<FilterDefinition<QuestContentEntity>> questBoardFilter(string? userGuid,
|
|
UgqUICategoryGradeType gradeType, UgqSearchType searchType, string? searchText,
|
|
IMongoCollection<AccountEntity> accountCollection,
|
|
IMongoCollection<NpcNameEntity> npcNameCollection)
|
|
{
|
|
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
|
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
|
|
|
filter &= filterBuilder.Eq(x => x.State, QuestContentState.Live);
|
|
|
|
if (string.IsNullOrEmpty(userGuid) == false)
|
|
filter &= filterBuilder.Eq(x => x.UserGuid, userGuid);
|
|
|
|
if(gradeType != UgqUICategoryGradeType.None)
|
|
{
|
|
var gradeTypes = getGradeTypes(gradeType);
|
|
filter &= filterBuilder.In(x => x.GradeType, gradeTypes);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(searchText) == false)
|
|
{
|
|
switch (searchType)
|
|
{
|
|
case UgqSearchType.Title:
|
|
filter &= searchTitle(filterBuilder, searchText);
|
|
break;
|
|
case UgqSearchType.Beacon:
|
|
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
|
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
|
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return filter;
|
|
}
|
|
|
|
public static async Task<FilterDefinition<QuestContentEntity>> questBoardBookmarkFilter(string userGuid,
|
|
UgqUICategoryGradeType gradeType, UgqSearchType searchType, string? searchText,
|
|
IMongoCollection<NpcNameEntity> npcNameCollection,
|
|
IMongoCollection<BookmarkEntity> bookmarkCollection)
|
|
{
|
|
var filterBuilder = Builders<QuestContentEntity>.Filter;
|
|
var filter = filterBuilder.Eq(x => x.IsDeleted, false);
|
|
|
|
filter &= filterBuilder.Eq(x => x.State, QuestContentState.Live);
|
|
|
|
if (gradeType != UgqUICategoryGradeType.None)
|
|
{
|
|
var gradeTypes = getGradeTypes(gradeType);
|
|
filter &= filterBuilder.In(x => x.GradeType, gradeTypes);
|
|
}
|
|
|
|
var bookmarkQuestIds = await getBookmarks(bookmarkCollection, userGuid);
|
|
filter &= filterBuilder.In(x => x.QuestId, bookmarkQuestIds);
|
|
|
|
if (string.IsNullOrEmpty(searchText) == false)
|
|
{
|
|
switch (searchType)
|
|
{
|
|
case UgqSearchType.Title:
|
|
filter &= searchTitle(filterBuilder, searchText);
|
|
break;
|
|
case UgqSearchType.Beacon:
|
|
var npcIds = await searchNpcs(npcNameCollection, searchText);
|
|
filter &= (filterBuilder.In(x => x.BeaconId, npcIds) |
|
|
filterBuilder.Regex(x => x.UgcBeaconNickname, searchText));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return filter;
|
|
}
|
|
|
|
public static SortDefinition<T> questBoardSort<T>(UgqSortType sortType)
|
|
{
|
|
var sortBuilder = Builders<T>.Sort;
|
|
SortDefinition<T> sort;
|
|
switch (sortType)
|
|
{
|
|
case UgqSortType.New:
|
|
sort = Builders<T>.Sort.Descending("UpdatedAt");
|
|
break;
|
|
case UgqSortType.Like:
|
|
sort = Builders<T>.Sort.Descending("LikeCount");
|
|
break;
|
|
case UgqSortType.Bookmark:
|
|
sort = Builders<T>.Sort.Descending("BookmarkCount");
|
|
break;
|
|
default:
|
|
sort = Builders<T>.Sort.Descending("UpdatedAt");
|
|
break;
|
|
}
|
|
|
|
return sort;
|
|
}
|
|
|
|
public static PipelineDefinition<QuestContentEntity, T> summariesPipeline<T>(
|
|
IMongoCollection<LikeEntity> likeCollection,
|
|
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
|
FilterDefinition<QuestContentEntity> filter,
|
|
Expression<Func<QuestSummariesQueryJoin, T>> projection)
|
|
{
|
|
var lookupStage1 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestAccepted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "pipeline",
|
|
new BsonArray
|
|
{
|
|
new BsonDocument("$match",
|
|
new BsonDocument("Reason", "Player"))
|
|
} },
|
|
{ "as", "QuestAccepteds" }
|
|
});
|
|
|
|
var addFields1 = new BsonDocument("$addFields",
|
|
new BsonDocument("QuestAcceptedCount",
|
|
new BsonDocument("$size", "$QuestAccepteds")));
|
|
|
|
var lookupStage2 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestCompleted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "as", "QuestCompleteds" }
|
|
});
|
|
|
|
var addFields2 = new BsonDocument("$addFields",
|
|
new BsonDocument("QuestCompletedCount",
|
|
new BsonDocument("$size", "$QuestCompleteds")));
|
|
|
|
var lookupStage3 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestAborted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "as", "QuestAborteds" }
|
|
});
|
|
|
|
var addFields3 = new BsonDocument("$addFields",
|
|
new BsonDocument("QuestAbortedCount",
|
|
new BsonDocument("$size", "$QuestAborteds")));
|
|
|
|
var lookupStage4 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "CreatorPointHistory" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "pipeline",
|
|
new BsonArray
|
|
{
|
|
new BsonDocument("$match",
|
|
new BsonDocument("Kind", "QuestProfit"))
|
|
} },
|
|
{ "as", "ProfitHistories" }
|
|
});
|
|
|
|
var addFields4 = new BsonDocument("$addFields",
|
|
new BsonDocument("TotalProfit",
|
|
new BsonDocument("$sum", "$ProfitHistories.Amount")));
|
|
|
|
|
|
var lookupStage5 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "Report" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "as", "Reports" }
|
|
});
|
|
|
|
var addFields5 = new BsonDocument("$addFields",
|
|
new BsonDocument("ReporCount",
|
|
new BsonDocument("$size", "$Reports")));
|
|
|
|
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
|
.Match(filter)
|
|
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestSummariesQueryJoin>(
|
|
likeCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Likes)
|
|
.Lookup<QuestContentEntity, QuestSummariesQueryJoin, BookmarkEntity, QuestSummariesQueryJoin>(
|
|
bookmarkCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Bookmarks)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage1)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields1)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage2)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields2)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage3)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields3)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage4)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields4)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(lookupStage5)
|
|
.AppendStage<QuestContentEntity, QuestSummariesQueryJoin, QuestSummariesQueryJoin>(addFields5)
|
|
|
|
.Project(projection);
|
|
|
|
return pipeline;
|
|
}
|
|
|
|
public static PipelineDefinition<QuestContentEntity, T> questProfitStatsPipeline<T>(
|
|
FilterDefinition<QuestContentEntity> filter,
|
|
Expression<Func<QuestProfitStatsQueryJoin, T>> projection)
|
|
{
|
|
var lookupStage1 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestCompleted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "as", "QuestCompleteds" }
|
|
});
|
|
|
|
var addFields1 = new BsonDocument("$addFields",
|
|
new BsonDocument("QuestCompletedCount",
|
|
new BsonDocument("$size", "$QuestCompleteds")));
|
|
|
|
var lookupStage2 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "CreatorPointHistory" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "pipeline",
|
|
new BsonArray
|
|
{
|
|
new BsonDocument("$match",
|
|
new BsonDocument("Kind", "QuestProfit"))
|
|
} },
|
|
{ "as", "ProfitHistories" }
|
|
});
|
|
|
|
var addFields2 = new BsonDocument("$addFields",
|
|
new BsonDocument("TotalProfit",
|
|
new BsonDocument("$sum", "$ProfitHistories.Amount")));
|
|
|
|
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
|
.Match(filter)
|
|
.AppendStage<QuestContentEntity, QuestContentEntity, QuestProfitStatsQueryJoin>(lookupStage1)
|
|
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(addFields1)
|
|
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(lookupStage2)
|
|
.AppendStage<QuestContentEntity, QuestProfitStatsQueryJoin, QuestProfitStatsQueryJoin>(addFields2)
|
|
|
|
.Project(projection);
|
|
|
|
return pipeline;
|
|
}
|
|
|
|
public static PipelineDefinition<QuestContentEntity, T> questBoardPipeline<T>(
|
|
IMongoCollection<LikeEntity> likeCollection,
|
|
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
|
FilterDefinition<QuestContentEntity> filter,
|
|
Expression<Func<QuestBoardQueryJoin, T>> projection)
|
|
{
|
|
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
|
.Match(filter)
|
|
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestBoardQueryJoin>(
|
|
likeCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Likes)
|
|
.Lookup<QuestContentEntity, QuestBoardQueryJoin, BookmarkEntity, QuestBoardQueryJoin>(
|
|
bookmarkCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Bookmarks)
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
|
.Project(projection);
|
|
|
|
return pipeline;
|
|
}
|
|
|
|
public static PipelineDefinition<QuestContentEntity, T> questBoardDetailPipeline<T>(
|
|
IMongoCollection<LikeEntity> likeCollection,
|
|
IMongoCollection<BookmarkEntity> bookmarkCollection,
|
|
FilterDefinition<QuestContentEntity> filter,
|
|
Expression<Func<QuestBoardQueryJoin, T>> projection)
|
|
{
|
|
var lookupStage1 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestAccepted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "pipeline",
|
|
new BsonArray
|
|
{
|
|
new BsonDocument("$match",
|
|
new BsonDocument("Reason", "Player"))
|
|
} },
|
|
{ "as", "QuestAccepteds" }
|
|
});
|
|
|
|
var lookupStage2 = new BsonDocument("$lookup",
|
|
new BsonDocument
|
|
{
|
|
{ "from", "QuestCompleted" },
|
|
{ "localField", "QuestId" },
|
|
{ "foreignField", "QuestId" },
|
|
{ "as", "QuestCompleteds" }
|
|
});
|
|
|
|
var pipeline = new EmptyPipelineDefinition<QuestContentEntity>()
|
|
.Match(filter)
|
|
.Lookup<QuestContentEntity, QuestContentEntity, LikeEntity, QuestBoardQueryJoin>(
|
|
likeCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Likes)
|
|
.Lookup<QuestContentEntity, QuestBoardQueryJoin, BookmarkEntity, QuestBoardQueryJoin>(
|
|
bookmarkCollection,
|
|
x => x.QuestId,
|
|
x => x.QuestId,
|
|
x => x.Bookmarks)
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>(lookupStage1)
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>(lookupStage2)
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {LikeCount: {$size:'$Likes'}}}")
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {BookmarkCount: {$size:'$Bookmarks'}}}")
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {QuestAcceptedCount: {$size:'$QuestAccepteds'}}}")
|
|
.AppendStage<QuestContentEntity, QuestBoardQueryJoin, QuestBoardQueryJoin>("{$addFields: {QuestCompletedCount: {$size:'$QuestCompleteds'}}}")
|
|
.Project(projection);
|
|
|
|
return pipeline;
|
|
}
|
|
}
|
|
|