private static void WriteData(
            JsonWriter jsonWriter,
            NuGetIndexSearcher searcher,
            TopDocs topDocs,
            int skip,
            int take,
            Uri baseAddress,
            bool includePrerelease,
            bool includeExplanation,
            NuGetVersion semVerLevel,
            Query query)
        {
            jsonWriter.WritePropertyName("data");

            jsonWriter.WriteStartArray();

            for (int i = skip; i < Math.Min(skip + take, topDocs.ScoreDocs.Length); i++)
            {
                ScoreDoc scoreDoc = topDocs.ScoreDocs[i];

                Document document = searcher.Doc(scoreDoc.Doc);

                jsonWriter.WriteStartObject();

                string id = document.Get("Id");

                var relativeAddress = UriFormatter.MakeRegistrationRelativeAddress(id);
                var absoluteAddress = new Uri(baseAddress, relativeAddress).AbsoluteUri;

                WriteProperty(jsonWriter, "@id", absoluteAddress);
                WriteProperty(jsonWriter, "@type", "Package");
                WriteProperty(jsonWriter, "registration", absoluteAddress);

                WriteProperty(jsonWriter, "id", id);

                WriteDocumentValue(jsonWriter, "version", document, LuceneMetadataConstants.FullVersionPropertyName);
                WriteDocumentValue(jsonWriter, "description", document, "Description");
                WriteDocumentValue(jsonWriter, "summary", document, "Summary");
                WriteDocumentValue(jsonWriter, "title", document, "Title");
                WriteDocumentValue(jsonWriter, "iconUrl", document, "IconUrl");
                WriteDocumentValue(jsonWriter, "licenseUrl", document, "LicenseUrl");
                WriteDocumentValue(jsonWriter, "projectUrl", document, "ProjectUrl");
                WriteDocumentValueAsArray(jsonWriter, "tags", document, "Tags");
                WriteDocumentValueAsArray(jsonWriter, "authors", document, "Authors", true);
                WriteProperty(jsonWriter, "totalDownloads", searcher.Versions[scoreDoc.Doc].AllVersionDetails.Select(item => item.Downloads).Sum());
                WriteProperty(jsonWriter, "verified", searcher.VerifiedPackages.Contains(id));
                WriteVersions(jsonWriter, baseAddress, id, includePrerelease, semVerLevel, searcher.Versions[scoreDoc.Doc]);

                if (includeExplanation)
                {
                    Explanation explanation = searcher.Explain(query, scoreDoc.Doc);
                    WriteProperty(jsonWriter, "explanation", explanation.ToString());
                    WriteProperty(jsonWriter, "score", scoreDoc.Score);
                }

                jsonWriter.WriteEndObject();
            }

            jsonWriter.WriteEndArray();
        }
 private static void WriteExplanations(JsonWriter jsonWriter, NuGetIndexSearcher searcher, TopDocs topDocs, int skip, int take, Query query)
 {
     jsonWriter.WritePropertyName("explanations");
     jsonWriter.WriteStartArray();
     for (int i = skip; i < Math.Min(skip + take, topDocs.ScoreDocs.Length); i++)
     {
         ScoreDoc    scoreDoc    = topDocs.ScoreDocs[i];
         Explanation explanation = searcher.Explain(query, scoreDoc.Doc);
         jsonWriter.WriteValue(explanation.ToString());
     }
     jsonWriter.WriteEndArray();
 }
        public static JToken MakeResultData(NuGetIndexSearcher searcher, string scheme, TopDocs topDocs, int skip, int take, NuGetSearcherManager searcherManager, bool includeExplanation, Query query)
        {
            Uri registrationBaseAddress = searcherManager.RegistrationBaseAddress[scheme];

            JArray array = new JArray();

            for (int i = skip; i < Math.Min(skip + take, topDocs.ScoreDocs.Length); i++)
            {
                ScoreDoc scoreDoc = topDocs.ScoreDocs[i];

                Document document = searcher.Doc(scoreDoc.Doc);

                string url = document.Get("Url");
                string id = document.Get("Id");
                string version = document.Get("Version");

                JObject obj = new JObject();
                obj["@id"] = new Uri(registrationBaseAddress, url).AbsoluteUri;
                obj["@type"] = "Package";
                obj["registration"] = new Uri(registrationBaseAddress, string.Format("{0}/index.json", id.ToLowerInvariant())).AbsoluteUri;
                obj["id"] = id;

                AddField(obj, document, "domain", "Domain");
                AddField(obj, document, "description", "Description");
                AddField(obj, document, "summary", "Summary");
                AddField(obj, document, "title", "Title");
                AddField(obj, document, "iconUrl", "IconUrl");
                AddField(obj, document, "licenseUrl", "LicenseUrl");
                AddField(obj, document, "projectUrl", "ProjectUrl");
                AddFieldAsArray(obj, document, "tags", "Tags");
                AddFieldAsArray(obj, document, "authors", "Authors");

                obj["version"] = version;
                obj["versions"] = searcherManager.GetVersions(searcher, scheme, scoreDoc.Doc);
                
                if (includeExplanation)
                {
                    Explanation explanation = searcher.Explain(query, scoreDoc.Doc);
                    obj["explanation"] = explanation.ToString();
                }

                array.Add(obj);
            }

            return array;
        }