/// <summary> /// Updates the search statistics /// </summary> /// <param name="repositoryParameter"></param> /// <param name="keywords"></param> /// <returns></returns> public async Task <SearchStatistics> Update(RepositoryQueryParameter repositoryParameter, IEnumerable <string> keywords) { void CheckParams() { if (repositoryParameter == null) { throw new ArgumentNullException(nameof(repositoryParameter)); } } CheckParams(); FilterDefinition <SearchStatistics> repoNameFilter = RepoCatFilterBuilder.BuildStatisticsRepositoryFilter(repositoryParameter.OrganizationName, repositoryParameter.RepositoryName); var statistics = await this.FindOneOrCreateNewAsync(repositoryParameter, repoNameFilter); foreach (string keyword in keywords) { if (string.IsNullOrWhiteSpace(keyword)) { continue; } var existing = statistics.SearchKeywordData.FirstOrDefault(x => string.Equals(x.Keyword, keyword, StringComparison.OrdinalIgnoreCase)); if (existing != null) { existing.SearchCount++; } else { statistics.SearchKeywordData.Add(new SearchKeywordData() { Keyword = keyword, SearchCount = 1 }); } } await this.searchStatisticsCollection.ReplaceOneAsync(repoNameFilter, statistics); return(statistics); }
private async Task <IEnumerable <Project> > ExecuteFilter(FilterDefinition <ProjectInfo> filter) { bool containsTextFilter = RepoCatFilterBuilder.CheckIfContainsTextFilter(filter); IAggregateFluent <ProjectWithRepos> aggr; if (containsTextFilter) { aggr = this.projects.Aggregate() .Match(filter) .Sort(Builders <ProjectInfo> .Sort.MetaTextScore("textScore")) .Lookup( foreignCollection: this.repositories, localField: prj => prj.RepositoryId, foreignField: repo => repo.Id, @as: (ProjectWithRepos pr) => pr.RepositoryInfo ); } else { aggr = this.projects.Aggregate() .Match(filter) .Lookup( foreignCollection: this.repositories, localField: prj => prj.RepositoryId, foreignField: repo => repo.Id, @as: (ProjectWithRepos pr) => pr.RepositoryInfo ); } IEnumerable <Project> projected = (await aggr.ToListAsync().ConfigureAwait(false)).Select(x => new Project() { ProjectInfo = x, RepositoryInfo = x.RepositoryInfo.First() }); return(projected); }
private async Task <DownloadStatistics> FindOneOrCreateNewAsync(ObjectId repositoryId, FilterDefinition <DownloadStatistics> repositoryFilter) { FindOneAndUpdateOptions <DownloadStatistics, DownloadStatistics> options = new FindOneAndUpdateOptions <DownloadStatistics, DownloadStatistics>() { IsUpsert = true, ReturnDocument = ReturnDocument.After }; UpdateDefinition <DownloadStatistics> updateDef = new UpdateDefinitionBuilder <DownloadStatistics>() .SetOnInsert(x => x.RepositoryId, repositoryId) ; try { return(await this.downloadsStatisticsCollection.FindOneAndUpdateAsync(RepoCatFilterBuilder.BuildStatisticsRepositoryFilter(repositoryId), updateDef, options) .ConfigureAwait(false)); } catch (MongoException) { //upsert might require a retry //https://docs.mongodb.com/manual/reference/method/db.collection.findAndModify/#upsert-and-unique-index //https://stackoverflow.com/questions/42752646/async-update-or-insert-mongodb-documents-using-net-driver return(await this.downloadsStatisticsCollection.FindOneAndUpdateAsync(repositoryFilter, updateDef, options) .ConfigureAwait(false)); } }
private async Task <IEnumerable <Project> > GetProjects(RepositoryInfo repository, string query, bool isRegex, string stamp = null) { FilterDefinition <ProjectInfo> filter = await RepoCatFilterBuilder.BuildProjectsFilter(this.projects, query, isRegex, repository, stamp).ConfigureAwait(false); return(await this.ExecuteFilter(filter).ConfigureAwait(false)); }
/// <summary> /// Gets all repositories from a give organization /// </summary> /// <param name="organizationName"></param> /// <returns></returns> public Task <IAsyncCursor <RepositoryInfo> > GetAllRepositories(string organizationName) { return(this.repositories.FindAsync(RepoCatFilterBuilder.BuildRepositoryFilter(organizationName))); }