private static void UpdateLatestVersionFacet(IDictionary <string, List <FacetedDocument> > existingValuesByFacet, IDictionary <string, FacetedDocument> candidateNewValueByFacet, string facet)
        {
            FacetedDocument newValue;

            if (candidateNewValueByFacet.TryGetValue(facet, out newValue))
            {
                List <FacetedDocument> existingValues;
                FacetedDocument        trueLatest = newValue;
                if (existingValuesByFacet.TryGetValue(facet, out existingValues))
                {
                    // Find the true latest
                    var oldLatest = existingValues.Where(d => d.Data.Package.Listed).OrderByDescending(d => d.Version).FirstOrDefault();
                    if (oldLatest != null && oldLatest.Version > trueLatest.Version)
                    {
                        trueLatest = oldLatest;
                    }

                    // Remove the facets from all the existing values, unless one of them happens to be the new one
                    foreach (var existing in existingValues)
                    {
                        if (existing != trueLatest)
                        {
                            existing.RemoveFacet(facet);
                        }
                    }
                }

                // Add the facet to the new value (this is idempotent, so it's ok if the document already has the facet)
                trueLatest.AddFacet(facet);
            }
        }
        private static void ProcessCompatibleVersion(string packageId, PerfEventTracker perfTracker, IDictionary <string, FacetedDocument> candidateNewFacets, FacetedDocument doc, FrameworkName projectFx)
        {
            using (perfTracker.TrackEvent("ProcessCompatibleVersion", "{0} v{1} (fx:{2})", packageId, doc.Version, projectFx))
            {
                // Add compatible facet
                doc.AddFacet(Facets.Compatible(projectFx));

                // If listed, process it against latest versions
                if (doc.Data.Package.Listed)
                {
                    // Check it against the current latest prerelease and swap latests if necessary
                    string latestPreFacet    = Facets.LatestPrereleaseVersion(projectFx);
                    string latestStableFacet = Facets.LatestStableVersion(projectFx);
                    if (!candidateNewFacets.ContainsKey(latestPreFacet))
                    {
                        candidateNewFacets[latestPreFacet] = doc;
                    }

                    // If this package is a stable version, do the same for latest stable
                    if (String.IsNullOrEmpty(doc.Version.SpecialVersion) && !candidateNewFacets.ContainsKey(latestStableFacet))
                    {
                        candidateNewFacets[latestStableFacet] = doc;
                    }
                }
            }
        }
        // ----------------------------------------------------------------------------------------------------------------------------------------
        private static Document CreateLuceneDocument(FacetedDocument documentData)
        {
            Package package = documentData.Data.Package;

            Document doc = new Document();

            //  Query Fields

            float titleBoost = 3.0f;
            float idBoost    = 2.0f;

            if (package.Tags == null)
            {
                titleBoost += 0.5f;
                idBoost    += 0.5f;
            }

            string title = package.Title ?? package.PackageRegistration.Id;

            Add(doc, "Id", package.PackageRegistration.Id, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, idBoost);
            Add(doc, "TokenizedId", package.PackageRegistration.Id, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, idBoost);
            Add(doc, "ShingledId", package.PackageRegistration.Id, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, idBoost);
            Add(doc, "Version", package.Version, Field.Store.YES, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, idBoost);
            Add(doc, "Title", title, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, titleBoost);
            Add(doc, "Tags", package.Tags, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS, 1.5f);
            Add(doc, "Description", package.Description, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
            Add(doc, "Authors", package.FlattenedAuthors, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);

            foreach (User owner in package.PackageRegistration.Owners)
            {
                Add(doc, "Owners", owner.Username, Field.Store.NO, Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS_OFFSETS);
            }

            //  Sorting:

            doc.Add(new NumericField("PublishedDate", Field.Store.YES, true).SetIntValue(int.Parse(package.Published.ToString("yyyyMMdd"))));

            DateTime lastEdited = package.LastEdited ?? package.Published;

            doc.Add(new NumericField("EditedDate", Field.Store.YES, true).SetIntValue(int.Parse(lastEdited.ToString("yyyyMMdd"))));

            string displayName = String.IsNullOrEmpty(package.Title) ? package.PackageRegistration.Id : package.Title;

            displayName = displayName.ToLower(CultureInfo.CurrentCulture);
            Add(doc, "DisplayName", displayName, Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO);

            Add(doc, "IsLatest", package.IsLatest ? 1 : 0, Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO);
            Add(doc, "IsLatestStable", package.IsLatestStable ? 1 : 0, Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO);
            Add(doc, "Listed", package.Listed ? 1 : 0, Field.Store.NO, Field.Index.NOT_ANALYZED, Field.TermVector.NO);

            if (documentData.Data.Feeds != null)
            {
                foreach (string feed in documentData.Data.Feeds)
                {
                    //  Store this to aid with debugging
                    Add(doc, "CuratedFeed", feed, Field.Store.YES, Field.Index.NOT_ANALYZED, Field.TermVector.NO);
                }
            }

            //  Add Package Key so we can quickly retrieve ranges of packages (in order to support the synchronization with the gallery)

            doc.Add(new NumericField("Key", Field.Store.YES, true).SetIntValue(package.Key));

            doc.Add(new NumericField("Checksum", Field.Store.YES, true).SetIntValue(documentData.Data.Checksum));

            //  Data we want to store in index - these cannot be queried

            JObject obj  = PackageJson.ToJson(package);
            string  data = obj.ToString(Formatting.None);

            Add(doc, "Data", data, Field.Store.YES, Field.Index.NO, Field.TermVector.NO);

            // Add facets
            foreach (var facet in documentData.DocFacets)
            {
                Add(doc, "Facet", facet, Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS, Field.TermVector.NO);
            }

            doc.Boost = DetermineLanguageBoost(package.PackageRegistration.Id, package.Language);

            return(doc);
        }
 private static void AddToExistingFacetsList(IDictionary <string, List <FacetedDocument> > existingFacets, FacetedDocument document, FrameworkName projectFx, string facet)
 {
     if (document.HasFacet(facet))
     {
         List <FacetedDocument> existingList;
         if (!existingFacets.TryGetValue(facet, out existingList))
         {
             existingList          = new List <FacetedDocument>();
             existingFacets[facet] = existingList;
         }
         existingList.Add(document);
     }
 }