private JsonDocument RetrieveDocumentInternal( IndexQueryResult queryResult, HashSet <string> loadedIds, FieldsToFetch fieldsToFetch, IndexDefinition indexDefinition, bool skipDuplicateCheck) { var queryScore = queryResult.Score; if (float.IsNaN(queryScore)) { queryScore = 0f; } if (queryResult.Projection == null) { // duplicate document, filter it out if (skipDuplicateCheck == false && loadedIds.Add(queryResult.Key) == false) { return(null); } var document = GetDocumentWithCaching(queryResult); if (document == null) { return(null); } document.Metadata = GetMetadata(document); if (skipDuplicateCheck == false) { document.Metadata[Constants.TemporaryScoreValue] = queryScore; } return(document); } JsonDocument doc = null; if (fieldsToFetch.IsProjection) { if (indexDefinition.IsMapReduce == false) { bool hasStoredFields = false; FieldStorage value; if (indexDefinition.Stores.TryGetValue(Constants.AllFields, out value)) { hasStoredFields = value != FieldStorage.No; } foreach (var fieldToFetch in fieldsToFetch.Fields) { if (indexDefinition.Stores.TryGetValue(fieldToFetch, out value) == false && value != FieldStorage.No) { continue; } hasStoredFields = true; } if (hasStoredFields == false) { // duplicate document, filter it out if (loadedIds.Add(queryResult.Key) == false) { return(null); } } } // We have to load the document if user explicitly asked for the id, since // we normalize the casing for the document id on the index, and we need to return // the id to the user with the same casing they gave us. var fetchingId = fieldsToFetch.HasField(Constants.DocumentIdFieldName); var fieldsToFetchFromDocument = fieldsToFetch.Fields.Where(fieldToFetch => queryResult.Projection[fieldToFetch] == null).ToArray(); if (fieldsToFetchFromDocument.Length > 0 || fetchingId) { switch (configuration.ImplicitFetchFieldsFromDocumentMode) { case ImplicitFetchFieldsMode.Enabled: doc = GetDocumentWithCaching(queryResult); if (doc != null) { if (fetchingId) { queryResult.Projection[Constants.DocumentIdFieldName] = doc.Key; } var result = doc.DataAsJson.SelectTokenWithRavenSyntax(fieldsToFetchFromDocument.ToArray()); foreach (var property in result) { if (property.Value == null) { continue; } queryResult.Projection[property.Key] = property.Value; } } break; case ImplicitFetchFieldsMode.DoNothing: break; case ImplicitFetchFieldsMode.Exception: string message = string.Format("Implicit fetching of fields from the document is disabled." + Environment.NewLine + "Check your index ({0}) to make sure that all fields you want to project are stored in the index." + Environment.NewLine + "You can control this behavior using the Raven/ImplicitFetchFieldsFromDocumentMode setting." + Environment.NewLine + "Fields to fetch from document are: {1}" + Environment.NewLine + "Fetching id: {2}", indexDefinition.Name, string.Join(", ", fieldsToFetchFromDocument), fetchingId); throw new ImplicitFetchFieldsFromDocumentNotAllowedException(message); default: throw new ArgumentOutOfRangeException(configuration.ImplicitFetchFieldsFromDocumentMode.ToString()); } } } else if (fieldsToFetch.FetchAllStoredFields && string.IsNullOrEmpty(queryResult.Key) == false && (fieldsToFetch.Query == null || fieldsToFetch.Query.AllowMultipleIndexEntriesForSameDocumentToResultTransformer == false) ) { // duplicate document, filter it out if (loadedIds.Add(queryResult.Key) == false) { return(null); } doc = GetDocumentWithCaching(queryResult); } var metadata = GetMetadata(doc); metadata.Remove("@id"); metadata[Constants.TemporaryScoreValue] = queryScore; return(new JsonDocument { Key = queryResult.Key, DataAsJson = queryResult.Projection, Metadata = metadata }); }
private JsonDocument RetrieveDocumentInternal( IndexQueryResult queryResult, HashSet <string> loadedIds, FieldsToFetch fieldsToFetch, IndexDefinition indexDefinition, bool skipDuplicateCheck) { var queryScore = queryResult.Score; if (float.IsNaN(queryScore)) { queryScore = 0f; } if (queryResult.Projection == null) { // duplicate document, filter it out if (skipDuplicateCheck == false && loadedIds.Add(queryResult.Key) == false) { return(null); } var document = GetDocumentWithCaching(queryResult.Key); if (document == null) { return(null); } document.Metadata = GetMetadata(document); if (skipDuplicateCheck == false) { document.Metadata[Constants.TemporaryScoreValue] = queryScore; } return(document); } JsonDocument doc = null; if (fieldsToFetch.IsProjection) { if (indexDefinition.IsMapReduce == false) { bool hasStoredFields = false; FieldStorage value; if (indexDefinition.Stores.TryGetValue(Constants.AllFields, out value)) { hasStoredFields = value != FieldStorage.No; } foreach (var fieldToFetch in fieldsToFetch.Fields) { if (indexDefinition.Stores.TryGetValue(fieldToFetch, out value) == false && value != FieldStorage.No) { continue; } hasStoredFields = true; } if (hasStoredFields == false) { // duplicate document, filter it out if (loadedIds.Add(queryResult.Key) == false) { return(null); } } } // We have to load the document if user explicitly asked for the id, since // we normalize the casing for the document id on the index, and we need to return // the id to the user with the same casing they gave us. var fetchingId = fieldsToFetch.HasField(Constants.DocumentIdFieldName); var fieldsToFetchFromDocument = fieldsToFetch.Fields.Where(fieldToFetch => queryResult.Projection[fieldToFetch] == null).ToArray(); if (fieldsToFetchFromDocument.Length > 0 || fetchingId) { doc = GetDocumentWithCaching(queryResult.Key); if (doc != null) { if (fetchingId) { queryResult.Projection[Constants.DocumentIdFieldName] = doc.Key; } var result = doc.DataAsJson.SelectTokenWithRavenSyntax(fieldsToFetchFromDocument.ToArray()); foreach (var property in result) { if (property.Value == null || property.Value.Type == JTokenType.Null) { continue; } queryResult.Projection[property.Key] = property.Value; } } } } else if (fieldsToFetch.FetchAllStoredFields && string.IsNullOrEmpty(queryResult.Key) == false && (fieldsToFetch.Query == null || fieldsToFetch.Query.AllowMultipleIndexEntriesForSameDocumentToResultTransformer == false) ) { // duplicate document, filter it out if (loadedIds.Add(queryResult.Key) == false) { return(null); } doc = GetDocumentWithCaching(queryResult.Key); } var metadata = GetMetadata(doc); metadata.Remove("@id"); metadata[Constants.TemporaryScoreValue] = queryScore; return(new JsonDocument { Key = queryResult.Key, DataAsJson = queryResult.Projection, Metadata = metadata }); }