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();
        }
Exemple #2
0
        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);
        }
Exemple #3
0
 public object AnyEq <TItem>(string arrayProperty, TItem item)
 {
     return(InternalBuilder.AnyEq(arrayProperty, item));
 }
Exemple #4
0
        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();
        }