public async Task LoadAsync() { var value = this.searchText; if (string.IsNullOrWhiteSpace(value)) { this.Searched = false; this.Things.Clear(); this.Words.Collection.Clear(); } else { this.Searched = true; var builder = new FilterDefinitionBuilder <Thing>(); FilterDefinition <Thing> filter; switch (this.SearchModes.Selected.Value.Value) { case SearchMode.Normal: filter = builder.Regex( PropertySelector <Thing> .Start().SelectMany(z => z.Words).Select(z => z.Text).ToString(), new Regex(Regex.Escape(value), RegexOptions.IgnoreCase)); break; case SearchMode.WholeWord: filter = builder.Eq(PropertySelector <Thing> .Start().SelectMany(z => z.Words).Select(z => z.Text).ToString(), value); break; default: throw new ArgumentOutOfRangeException(); } string category = null; if (this.ExistsCategorys.Selected != string.Empty) { category = this.ExistsCategorys.Selected; filter = filter & builder.AnyEq(z => z.Categorys, this.ExistsCategorys.Selected); } filter = builder.Eq(z => z.Id, value) | filter; var queryResult = await App.Current.ThingSetAccessor.FindAsync(filter, 20); this.HasNext = queryResult.HasNext; var sortedItems = await queryResult.Items .OrderBy(z => z.Words.Any(x => x.Text == value)? -1 : 1) .ThenBy(z => z.Words.Any(x => x.Text.Equals(value, StringComparison.OrdinalIgnoreCase)) ? -1 : 1) .ToArrayAsync(); this.Things.Reset(sortedItems.Select(z => new ThingViewModel(z, category))); this.Words.Collection.Reset(this.Things.SelectMany(z => z.Words)); } this.RefreshProperties(); }
public async Task <List <Repository> > QueryByKeyAndTag(string tenant, string repository, string collection, string key, string tag) { IMongoCollection <Repository> repositoryCollection = ConnectToCollection(repository, collection); FilterDefinitionBuilder <Repository> builder = Builders <Repository> .Filter; FilterDefinition <Repository> compositeFilter = builder.Eq(t => t.tenant, tenant) & builder.Eq(k => k.key, key) & builder.AnyEq("tags", tag); var found = await repositoryCollection.Find(compositeFilter).ToListAsync(); if (found is null) { throw new RepoSvcDocumentNotFoundException($"tag: {tag}"); } return(found); }
public object AnyEq <TItem>(string arrayProperty, TItem item) { return(InternalBuilder.AnyEq(arrayProperty, item)); }
private static Task StartRadioFeeder(RadioCastServer radioCastServer, MongoWrapper mongoWrapper) { var userCollection = mongoWrapper.Database.GetCollection <Models.Musician>(nameof(Models.User)); var songSortBuilder = new SortDefinitionBuilder <ProjectedMusicianSong>(); var songSort = songSortBuilder .Descending(nameof(ProjectedMusicianSong.Score)); var userFilterBuilder = new FilterDefinitionBuilder <Models.Musician>(); var userFilter = userFilterBuilder.And ( GeneralUtils.NotDeactivated(userFilterBuilder), userFilterBuilder.AnyEq("_t", nameof(Models.Musician)) ); var songFilterBuilder = new FilterDefinitionBuilder <ProjectedMusicianSong>(); var songFilter = songFilterBuilder.And ( GeneralUtils.NotDeactivated(songFilterBuilder, s => s.Song), songFilterBuilder.Eq(s => s.Song.RadioAuthorized, true), songFilterBuilder.Eq(s => s.Song.Original, true) ); var projectionBuilder = new ProjectionDefinitionBuilder <Models.Musician>(); var projection = projectionBuilder.Include(m => m.FullName).Include(m => m.Songs); var fsBucket = new GridFSBucket <ObjectId>(mongoWrapper.Database); var trackHistory = new List <(IAudioSource, ProjectedMusicianSong)>(); var onTrackChangedTE = new ManualResetEvent(true); radioCastServer.OnTrackChanged += async(s, e) => { List <(IAudioSource, ProjectedMusicianSong)> myTrackHistory; lock (trackHistory) { myTrackHistory = trackHistory.ToList(); } RadioInfoController.CurrentSong = myTrackHistory.Where(th => th.Item1.Equals(e.NewTrack)).Select(th => th.Item2).LastOrDefault(); LOGGER.Info("Now playing: {}", JsonConvert.SerializeObject(RadioInfoController.CurrentSong)); onTrackChangedTE.Set(); if (e.OldTrack == null) { return; } var oldTrack = myTrackHistory.Where(th => th.Item1.Equals(e.OldTrack)).Select(th => th.Item2).LastOrDefault(); var oldMusicianId = oldTrack._id; var oldTrackId = oldTrack.Song._id; var musSongFilterBuilder = new FilterDefinitionBuilder <Models.Musician>(); var musSongFilter = musSongFilterBuilder.And ( musSongFilterBuilder.Eq(m => m._id, oldMusicianId), musSongFilterBuilder.ElemMatch(m => m.Songs, sg => sg._id == oldTrackId) ); var musSongUpdate = new UpdateDefinitionBuilder <Models.Musician>() .Inc($"{nameof(Models.Musician.Songs)}.$.{nameof(Song.TimesPlayedRadio)}", 1); await userCollection.UpdateOneAsync(musSongFilter, musSongUpdate); // Remove oldest, only keep 5 in history if (myTrackHistory.Count > 5) { lock (trackHistory) { trackHistory.RemoveAt(0); } } }; return(Task.Run(async() => { while (true) { List <(IAudioSource, ProjectedMusicianSong)> myTrackHistory; lock (trackHistory) { myTrackHistory = trackHistory.ToList(); } var lookupStageRandomArr = $@" {{ $lookup: {{ from: ""randomNumbers"", pipeline: [ {{ $sample: {{ size: 2 }} }} ], as: ""RandomArr"" }} }} "; // OK Vezes totais que a música foi tocada * 0.5 // OK Vezes totais que a música foi tocada na rádio * -1 // OK Se música está presente na lista das últimas 5 tocadas, -100 // OK Se o autor da música está presente na lista das últimas 5 tocadas, -50 // OK Pontuação aleatória para cada música, entre - 10 e + 10 // OK Número de dias desde o cadastramento da música * -1 // OK Há uma chance de 5% de multiplicar a pontuação resultante por -1 (efeito nostalgia) var scoreStage = $@" {{ $addFields: {{ ""Score"": {{ $add: [ {{ $multiply: [ ""$Song.timesPlayed"", 0.5 ] }}, {{ $multiply: [ ""$Song.timesPlayedRadio"", -1 ] }}, {{ $cond: {{ if: {{ $in: [ ""$_id"", [ {myTrackHistory.Select(th => $"ObjectId(\"{th.Item2._id.ToString()}\")").DefaultIfEmpty("").Aggregate((s1, s2) => $"{s1.TrimEnd(',')},{s2.TrimEnd(',')},").TrimEnd(',')} ] ] }}, then: -50, else: 0 }} }}, {{ $cond: {{ if: {{ $in: [ ""$Song._id"", [ {myTrackHistory.Select(th => $"ObjectId(\"{th.Item2.Song._id.ToString()}\")").DefaultIfEmpty("").Aggregate((s1, s2) => $"{s1.TrimEnd(',')},{s2.TrimEnd(',')},").TrimEnd(',')} ] ] }}, then: -100, else: 0 }} }}, {{ $add: [ {{ $multiply: [ {{ $toDecimal: {{ $arrayElemAt: [""$RandomArr.decimal"", 0] }} }}, 21 ] }}, -10 ] }}, {{ $multiply: [ {{ $divide: [ {{ $subtract: [ {{ $toDate: ""{DateTime.UtcNow.ToString("o")}"" }}, {{ $toDate: ""$Song._id"" }} ] }}, NumberLong(""86400000"") ] }}, {{ $cond: {{ if: {{ $gt: [ {{ $toDecimal: {{ $arrayElemAt: [""$RandomArr.decimal"", 1] }} }}, NumberDecimal(""0.1"") ] }}, then: -1, else: 1 }} }} ] }} ] }} }} }}"; LOGGER.Info("Score stage generated MongoDB query: {}", scoreStage); var pipeline = PipelineDefinitionBuilder .For <Models.Musician>() .Match(userFilter) .Unwind(m => m.Songs, new AggregateUnwindOptions <Models.Musician> { PreserveNullAndEmptyArrays = false, IncludeArrayIndex = null, }) .Project(m => new ProjectedMusicianSong { _id = m._id, Song = (Song)m.Songs, Score = 1, }) .Match(songFilter) .AppendStage <Musician, ProjectedMusicianSong, ProjectedMusicianSong>(lookupStageRandomArr) .AppendStage <Musician, ProjectedMusicianSong, ProjectedMusicianSong>(scoreStage) .Sort(songSort) .Limit(1); if (LOGGER.IsDebugEnabled) { LOGGER.Debug("Pipeline generated MongoDB query for song: {}", pipeline.ToString()); } var findTask = userCollection.AggregateAsync(pipeline, new AggregateOptions { AllowDiskUse = true, BatchSize = 1, UseCursor = true, Comment = "Radio Aggregate Query", TranslationOptions = new ExpressionTranslationOptions { StringTranslationMode = AggregateStringTranslationMode.CodePoints } }); var findResult = await findTask; var firstSong = findResult.SingleOrDefault(); // If no songs, wait a minute before checking again // Mostly not to strain the CPU on development environments if (firstSong?.Song == null) { Thread.Sleep(TimeSpan.FromMinutes(1)); continue; } LOGGER.Info("Next selected song: {}", JsonConvert.SerializeObject(firstSong)); var audioRef = firstSong.Song.AudioReference; var gridId = audioRef._id; var fileStreamTask = fsBucket.OpenDownloadStreamAsync(gridId, new GridFSDownloadOptions { Seekable = true, CheckMD5 = false, }); var audioSource = new Mp3FileAudioSource(await fileStreamTask, firstSong.Song.Name); // Wait for the radio to need more songs before we add the track we have on our hands while (radioCastServer.TrackCount > 1) { onTrackChangedTE.WaitOne(); onTrackChangedTE.Reset(); } lock (trackHistory) { trackHistory.Add((audioSource, firstSong)); } radioCastServer.AddTrack(audioSource); } })); }
private static void Main(string[] args) { var client = new MongoClient("[your connectionstring]"); IMongoDatabase db = client.GetDatabase("somedb"); db.DropCollection("people"); IMongoCollection <Person> collection = db.GetCollection <Person>("people"); collection.InsertOne(new Person { FirstName = "Bill", LastName = "Gates", Interests = new List <string> { "Microsoft", "Philanthropy", "Being rich" } }); var people = collection.Find(_ => true).ToList(); foreach (var p in people) { Console.WriteLine($"{p.Id} - {p.FirstName} {p.LastName} - {string.Join(',', p.Interests)}"); } collection.InsertMany(new[] { new Person { FirstName = "Steve", LastName = "Ballmer", Interests = new List <string> { "Basketball", "Developers", "Being rich" } }, new Person { FirstName = "Satya", LastName = "Nadella", Interests = new List <string> { "Open source", "Microsoft" } } }); Console.WriteLine(); var builder = new FilterDefinitionBuilder <Person>(); var definition = builder.AnyEq(p => p.Interests, "Being rich"); people = collection.Find(definition).ToList(); foreach (var p in people) { Console.WriteLine($"{p.Id} - {p.FirstName} {p.LastName} - {string.Join(',', p.Interests)}"); } Console.WriteLine("Press any key to continue"); Console.ReadKey(); }