diff --git a/src/Corax/Mappings/IndexFieldBinding.cs b/src/Corax/Mappings/IndexFieldBinding.cs
index 0945d7f09530..57dc805d776a 100644
--- a/src/Corax/Mappings/IndexFieldBinding.cs
+++ b/src/Corax/Mappings/IndexFieldBinding.cs
@@ -16,10 +16,10 @@ public sealed class IndexFieldBinding
private Analyzer _analyzer;
public readonly bool HasSuggestions;
public readonly bool HasSpatial;
- public FieldIndexingMode FieldIndexingMode => _silentlyChangedIndexingMode ?? _fieldIndexingMode;
+ public FieldIndexingMode FieldIndexingMode => _silentlyChangedIndexingModeLegacy ?? _fieldIndexingMode;
private readonly FieldIndexingMode _fieldIndexingMode;
public readonly bool ShouldStore;
- private FieldIndexingMode? _silentlyChangedIndexingMode;
+ private FieldIndexingMode? _silentlyChangedIndexingModeLegacy;
private string _fieldName;
private readonly bool _isFieldBindingForWriter;
@@ -75,7 +75,7 @@ public void OverrideFieldIndexingMode(FieldIndexingMode mode)
{
AssertBindingIsMadeForIndexing();
- _silentlyChangedIndexingMode = mode;
+ _silentlyChangedIndexingModeLegacy = mode;
}
public void SetAnalyzer(Analyzer analyzer)
diff --git a/src/Raven.Server/Config/Categories/IndexingConfiguration.cs b/src/Raven.Server/Config/Categories/IndexingConfiguration.cs
index d868ddeba59e..fce983b8fcf9 100644
--- a/src/Raven.Server/Config/Categories/IndexingConfiguration.cs
+++ b/src/Raven.Server/Config/Categories/IndexingConfiguration.cs
@@ -580,6 +580,12 @@ public virtual bool RunInMemory
[IndexUpdateType(IndexUpdateType.None)]
public IndexResetMode ResetMode { get; set; }
+ [Description("The default complex field indexing behavior for static Corax indexes")]
+ [DefaultValue(CoraxComplexFieldIndexingBehavior.Throw)]
+ [IndexUpdateType(IndexUpdateType.Reset)]
+ [ConfigurationEntry("Indexing.Corax.Static.ComplexFieldIndexingBehavior", ConfigurationEntryScope.ServerWideOrPerDatabaseOrPerIndex)]
+ public CoraxComplexFieldIndexingBehavior CoraxStaticIndexComplexFieldIndexingBehavior { get; protected set; }
+
protected override void ValidateProperty(PropertyInfo property)
{
base.ValidateProperty(property);
@@ -617,5 +623,12 @@ public enum IndexStartupBehaviorType
Pause,
Delay
}
+
+ public enum CoraxComplexFieldIndexingBehavior
+ {
+ None,
+ Throw,
+ Skip
+ }
}
}
diff --git a/src/Raven.Server/Documents/Indexes/Index.cs b/src/Raven.Server/Documents/Indexes/Index.cs
index 0b2d8b168260..50615f8026b1 100644
--- a/src/Raven.Server/Documents/Indexes/Index.cs
+++ b/src/Raven.Server/Documents/Indexes/Index.cs
@@ -959,6 +959,9 @@ protected virtual void LoadValues()
LastIndexingTime = _indexStorage.ReadLastIndexingTime(tx);
MaxNumberOfOutputsPerDocument = _indexStorage.ReadMaxNumberOfOutputsPerDocument(tx);
ArchivedDataProcessingBehavior = _indexStorage.ReadArchivedDataProcessingBehavior(tx);
+
+ if (SearchEngineType is SearchEngineType.Corax)
+ CoraxComplexFieldIndexingBehavior = _indexStorage.ReadCoraxComplexFieldIndexingBehavior(tx);
}
}
@@ -4489,7 +4492,7 @@ private Size? TransactionSizeLimit
}
}
-
+ public IndexingConfiguration.CoraxComplexFieldIndexingBehavior CoraxComplexFieldIndexingBehavior { get; private set; }
public ArchivedDataProcessingBehavior ArchivedDataProcessingBehavior { get; private set; }
diff --git a/src/Raven.Server/Documents/Indexes/IndexDefinitionBaseServerSide.cs b/src/Raven.Server/Documents/Indexes/IndexDefinitionBaseServerSide.cs
index effeb560dea8..0603ab7688c8 100644
--- a/src/Raven.Server/Documents/Indexes/IndexDefinitionBaseServerSide.cs
+++ b/src/Raven.Server/Documents/Indexes/IndexDefinitionBaseServerSide.cs
@@ -178,11 +178,12 @@ public static class IndexVersion
public const long StoreOnlySupportInCoraxIndexes = 60_003; // RavenDB-22369
public const long JavaScriptProperlyHandleDynamicFieldsIndexFields = 60_004; // RavenDB-22363
public const long LoadDocumentWithDynamicCollectionNameShouldThrow = 61_000; // RavenDB-22359
+ public const long CoraxComplexFieldIndexingBehavior = 61_0001;
///
/// Remember to bump this
///
- public const long CurrentVersion = LoadDocumentWithDynamicCollectionNameShouldThrow;
+ public const long CurrentVersion = CoraxComplexFieldIndexingBehavior;
public static bool IsTimeTicksInJavaScriptIndexesSupported(long indexVersion)
{
diff --git a/src/Raven.Server/Documents/Indexes/IndexStorage.cs b/src/Raven.Server/Documents/Indexes/IndexStorage.cs
index 1cfe72973e6c..5d92108b63ea 100644
--- a/src/Raven.Server/Documents/Indexes/IndexStorage.cs
+++ b/src/Raven.Server/Documents/Indexes/IndexStorage.cs
@@ -8,6 +8,7 @@
using Raven.Client.Documents.Operations.DataArchival;
using Raven.Client.Util;
using Raven.Server.Config;
+using Raven.Server.Config.Categories;
using Raven.Server.Documents.Indexes.Static;
using Raven.Server.Exceptions;
using Raven.Server.Indexing;
@@ -154,11 +155,14 @@ private unsafe void CreateSchema(DocumentDatabase documentDatabase)
void PersistConfiguration()
{
var configurationTree = tx.InnerTransaction.CreateTree(IndexSchema.ConfigurationTree);
- PersistSearchEngine(configurationTree);
+ var searchEngine = PersistSearchEngine(configurationTree);
AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultAnalyzer), _index.Configuration.DefaultAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.Default);
AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultExactAnalyzer), _index.Configuration.DefaultExactAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.DefaultExact);
AssertAndPersistAnalyzer(configurationTree, RavenConfiguration.GetKey(x => x.Indexing.DefaultSearchAnalyzer), _index.Configuration.DefaultSearchAnalyzer, Raven.Client.Constants.Documents.Indexing.Analyzers.DefaultSearch);
PersistArchivedDataProcessingBehavior(configurationTree, _index.GetDefaultArchivedDataProcessingBehavior());
+
+ if (searchEngine is SearchEngineType.Corax)
+ PersistCoraxComplexFieldIndexingBehavior(configurationTree);
}
void AssertAndPersistAnalyzer(Tree configurationTree, string configurationKey, string expectedAnalyzer, string defaultAnalyzer)
@@ -181,7 +185,7 @@ void AssertAndPersistAnalyzer(Tree configurationTree, string configurationKey, s
configurationTree.Add(configurationKey, expectedAnalyzer);
}
- void PersistSearchEngine(Tree configurationTree)
+ SearchEngineType PersistSearchEngine(Tree configurationTree)
{
string configurationKey = nameof(SearchEngineType);
string configurationName = _index.Type.IsAuto() ? RavenConfiguration.GetKey(x => x.Indexing.AutoIndexingEngineType) : RavenConfiguration.GetKey(x => x.Indexing.StaticIndexingEngineType);
@@ -198,13 +202,21 @@ void PersistSearchEngine(Tree configurationTree)
{
throw new InvalidDataException($"Invalid search engine for {_index.Name} was saved previously or it's corrupted. Please reset the index.");
}
+
+ return persistedSearchEngineType;
}
else
{
+ SearchEngineType type;
+
if (_index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.EngineTypeStored)
- configurationTree.Add(configurationKey, SearchEngineType.Lucene.ToString());
+ type = SearchEngineType.Lucene;
else
- configurationTree.Add(configurationKey, defaultEngineType.ToString());
+ type = defaultEngineType;
+
+ configurationTree.Add(configurationKey, type.ToString());
+
+ return type;
}
}
@@ -222,6 +234,29 @@ void PersistArchivedDataProcessingBehavior(Tree configurationTree, ArchivedDataP
configurationTree.Add(configurationKey, defaultBehavior.ToString());
}
}
+
+ void PersistCoraxComplexFieldIndexingBehavior(Tree configurationTree)
+ {
+ if (_index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.CoraxComplexFieldIndexingBehavior)
+ return;
+
+ const string configurationKey = nameof(IndexingConfiguration.CoraxComplexFieldIndexingBehavior);
+
+ var configuredBehavior = _index.Configuration.CoraxStaticIndexComplexFieldIndexingBehavior;
+
+ var result = configurationTree.Read(configurationKey);
+ if (result != null)
+ {
+ if (Enum.TryParse(result.Reader.ToStringValue(), out IndexingConfiguration.CoraxComplexFieldIndexingBehavior persistedCoraxStaticIndexComplexFieldIndexingBehavior) == false)
+ {
+ throw new InvalidDataException($"Invalid indexing complex field behavior in '{_index.Name}' Corax index");
+ }
+ }
+ else
+ {
+ configurationTree.Add(configurationKey, configuredBehavior.ToString());
+ }
+ }
}
}
@@ -507,6 +542,31 @@ public ArchivedDataProcessingBehavior ReadArchivedDataProcessingBehavior(RavenTr
return persistedArchivedDataProcessingBehavior;
}
+ public IndexingConfiguration.CoraxComplexFieldIndexingBehavior ReadCoraxComplexFieldIndexingBehavior(RavenTransaction tx)
+ {
+ if (_index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.CoraxComplexFieldIndexingBehavior)
+ return IndexingConfiguration.CoraxComplexFieldIndexingBehavior.None;
+
+ var configurationTree = tx.InnerTransaction.ReadTree(IndexSchema.ConfigurationTree);
+ if (configurationTree == null)
+ {
+ throw new InvalidOperationException($"Index does not contain {nameof(IndexSchema.ConfigurationTree)}' tree.");
+ }
+
+ var result = configurationTree.Read(IndexSchema.CoraxComplexFieldIndexingBehavior);
+ if (result == null)
+ {
+ throw new InvalidOperationException($"Index does not contain {nameof(IndexSchema.CoraxComplexFieldIndexingBehavior)}' key.");
+ }
+
+ if (Enum.TryParse(result.Reader.ToStringValue(), out IndexingConfiguration.CoraxComplexFieldIndexingBehavior persistedCoraxStaticIndexComplexFieldIndexingBehavior) == false)
+ {
+ throw new InvalidDataException($"Invalid indexing complex field behavior in '{_index.Name}' Corax index. It has: {result.Reader.ToStringValue()} defined.");
+ }
+
+ return persistedCoraxStaticIndexComplexFieldIndexingBehavior;
+ }
+
public sealed class DocumentReferences : ReferencesBase
{
public DocumentReferences()
@@ -1187,6 +1247,8 @@ internal sealed class IndexSchema
public static readonly Slice SearchEngineType;
+ public static readonly Slice CoraxComplexFieldIndexingBehavior;
+
static IndexSchema()
{
using (StorageEnvironment.GetStaticContext(out var ctx))
@@ -1213,6 +1275,7 @@ static IndexSchema()
Slice.From(ctx, "Time", ByteStringType.Immutable, out TimeSlice);
Slice.From(ctx, nameof(Client.Documents.Indexes.SearchEngineType), ByteStringType.Immutable, out SearchEngineType);
Slice.From(ctx, nameof(ArchivedDataProcessingBehavior), ByteStringType.Immutable, out ArchivedDataProcessingBehaviorSlice);
+ Slice.From(ctx, nameof(CoraxComplexFieldIndexingBehavior), ByteStringType.Immutable, out CoraxComplexFieldIndexingBehavior);
}
}
}
diff --git a/src/Raven.Server/Documents/Indexes/Persistence/Corax/CoraxDocumentConverterBase.cs b/src/Raven.Server/Documents/Indexes/Persistence/Corax/CoraxDocumentConverterBase.cs
index 06bc273152fd..40b290cd1c36 100644
--- a/src/Raven.Server/Documents/Indexes/Persistence/Corax/CoraxDocumentConverterBase.cs
+++ b/src/Raven.Server/Documents/Indexes/Persistence/Corax/CoraxDocumentConverterBase.cs
@@ -26,7 +26,9 @@
using System.IO;
using System.Text;
using Corax.Indexing;
+using Raven.Server.Config;
using Sparrow.Binary;
+using static Raven.Server.Config.Categories.IndexingConfiguration;
namespace Raven.Server.Documents.Indexes.Persistence.Corax;
@@ -35,6 +37,7 @@ public abstract class CoraxDocumentConverterBase : ConverterBase
protected byte[] _compoundFieldsBuffer;
private readonly bool _canContainSourceDocumentId;
+ private readonly bool _legacyHandlingOfComplexFields;
private static ReadOnlySpan TrueLiteral => "true"u8;
private static ReadOnlySpan FalseLiteral => "false"u8;
@@ -79,6 +82,8 @@ protected CoraxDocumentConverterBase(Index index, bool storeValue, bool indexImp
keyFieldName, storeValueFieldName, fields)
{
_canContainSourceDocumentId = canContainSourceDocumentId;
+ _legacyHandlingOfComplexFields = _index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.CoraxComplexFieldIndexingBehavior;
+
Allocator = new ByteStringContext(SharedMultipleUseFlag.None);
Scope = new();
@@ -326,17 +331,26 @@ protected void InsertRegularField(IndexField field, object value, Json
return;
}
-
- if (field.Indexing is not FieldIndexing.No)
- AssertOrAdjustIndexingOptionForComplexObject(field);
+
+ if (field.Indexing is not FieldIndexing.No)
+ {
+ if (_legacyHandlingOfComplexFields)
+ ComplexObjectInStaticIndexLegacyHandling(field);
+ else
+ AssertIndexingBehaviorForComplexObjectInStaticIndex(field);
+ }
if (_index.SourceDocumentIncludedInOutput == false && sourceDocument == value)
{
_index.SourceDocumentIncludedInOutput = true;
}
-
- var dynamicJson = (DynamicBlittableJson)value;
- builder.Store(fieldId, path, dynamicJson.BlittableJson);
+
+ if (field.Storage is FieldStorage.Yes || _legacyHandlingOfComplexFields)
+ {
+ var dynamicJson = (DynamicBlittableJson)value;
+ builder.Store(fieldId, path, dynamicJson.BlittableJson);
+ }
+
break;
case ValueType.Dictionary:
@@ -358,11 +372,15 @@ protected void InsertRegularField(IndexField field, object value, Json
if (field.Indexing is not FieldIndexing.No)
{
- AssertOrAdjustIndexingOptionForComplexObject(field);
- break;
+ if (_legacyHandlingOfComplexFields)
+ ComplexObjectInStaticIndexLegacyHandling(field);
+ else
+ AssertIndexingBehaviorForComplexObjectInStaticIndex(field);
}
- builder.Store(fieldId, path, jsonScope);
+ if (field.Storage is FieldStorage.Yes || _legacyHandlingOfComplexFields)
+ builder.Store(fieldId, path, jsonScope);
+
break;
case ValueType.BlittableJsonObject:
@@ -409,24 +427,51 @@ private static void ThrowFieldIsNoIndexedAndStored(IndexField field)
throw new InvalidOperationException($"A field `{field.Name}` that is neither indexed nor stored is useless because it cannot be searched or retrieved.");
}
- private void AssertOrAdjustIndexingOptionForComplexObject(IndexField field)
+ private void AssertIndexingBehaviorForComplexObjectInStaticIndex(IndexField field)
{
+ Debug.Assert(_index.Type.IsStatic(), $"It is is supposed to be called for static indexes only while we got {_index.Type} index");
+
if (IgnoreComplexObjectsDuringIndex)
return;
-
- Debug.Assert(field.Indexing != FieldIndexing.No, "field.Indexing != FieldIndexing.No");
- if (_index.GetIndexDefinition().Fields.TryGetValue(field.Name, out var fieldFromDefinition) &&
- fieldFromDefinition.Indexing != null &&
- fieldFromDefinition.Indexing != FieldIndexing.No)
+ switch (_index.CoraxComplexFieldIndexingBehavior)
{
- // We need to disable the complex object handling after we check and then throw.
- DisableIndexingForComplexObject(field);
- ThrowIndexingComplexObjectNotSupported(field, _index.Type);
+ case CoraxComplexFieldIndexingBehavior.Throw:
+ ThrowIndexingComplexObjectNotSupportedInStaticIndex(field, _index.Definition.Version);
+ break;
+ case CoraxComplexFieldIndexingBehavior.Skip:
+ // static Corax indexes don't support indexing of complex objects, so we're not going to index it anyway
+ break;
+ default:
+ throw new NotSupportedException(
+ $"Unknown {nameof(CoraxComplexFieldIndexingBehavior)} option: {_index.CoraxComplexFieldIndexingBehavior}");
}
+ }
- DisableIndexingForComplexObject(field);
+ private void ComplexObjectInStaticIndexLegacyHandling(IndexField field)
+ {
+ // Backward compatibility for older indexes
+ // Previously, we silently changed the definition not to throw when encountering a complex field without any particular configuration.
+ if (IgnoreComplexObjectsDuringIndex)
+ return;
+
+ Debug.Assert(_index.Type.IsStatic(), "Legacy complex field handling is supposed to be called for static indexes");
+ Debug.Assert(field.Indexing != FieldIndexing.No, "field.Indexing != FieldIndexing.No");
+ Debug.Assert(_index.Definition.Version < IndexDefinitionBaseServerSide.IndexVersion.CoraxComplexFieldIndexingBehavior, "Legacy complex field handling is supposed to be called only for old indexes");
+
+ // Skip indexing of this complex field for current and next entries by overwriting field.Indexing option by FieldIndexing.No
+
+ DisableIndexingForComplexObjectLegacyHandling(field);
+
+ if (_index.GetIndexDefinition().Fields.TryGetValue(field.Name, out var fieldFromDefinition) &&
+ fieldFromDefinition.Indexing is { } and not FieldIndexing.No)
+ {
+ // Indexing option was set explicitly in the definition. We'll throw in that case but only for the first encountered entry.
+ // The next ones will not index this field at all because we just disabled indexing for that field
+
+ ThrowIndexingComplexObjectNotSupportedInStaticIndex(field, _index.Definition.Version);
+ }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -446,26 +491,35 @@ void HandleObject(BlittableJsonReaderObject val, IndexField field, Jso
InsertRegularField(field, CoraxConstants.JsonValue, indexContext, builder, sourceDocument, out shouldSkip);
return;
}
+
+ if (field.Indexing is not FieldIndexing.No)
+ {
+ if (_legacyHandlingOfComplexFields)
+ ComplexObjectInStaticIndexLegacyHandling(field);
+ else
+ AssertIndexingBehaviorForComplexObjectInStaticIndex(field);
+ }
- if (field.Indexing is not FieldIndexing.No)
- AssertOrAdjustIndexingOptionForComplexObject(field);
if (GetKnownFieldsForWriter().TryGetByFieldId(field.Id, out var binding))
binding.SetAnalyzer(null);
- if (val.HasParent)
+ if (field.Storage is FieldStorage.Yes || _legacyHandlingOfComplexFields)
{
- using var clonedBlittable = val.CloneOnTheSameContext();
- builder.Store(field.Id, field.Name,clonedBlittable);
- }
- else
- {
- builder.Store(field.Id, field.Name,val);
+ if (val.HasParent)
+ {
+ using var clonedBlittable = val.CloneOnTheSameContext();
+ builder.Store(field.Id, field.Name, clonedBlittable);
+ }
+ else
+ {
+ builder.Store(field.Id, field.Name, val);
+ }
}
shouldSkip = false;
}
- private void DisableIndexingForComplexObject(IndexField field)
+ private void DisableIndexingForComplexObjectLegacyHandling(IndexField field)
{
field.Indexing = FieldIndexing.No;
_complexFields ??= new();
@@ -478,25 +532,28 @@ private void DisableIndexingForComplexObject(IndexField field)
}
[DoesNotReturn]
- internal static void ThrowIndexingComplexObjectNotSupported(IndexField field, IndexType indexType)
+ internal static void ThrowIndexingComplexObjectNotSupportedInStaticIndex(IndexField field, long indexVersion)
{
var fieldName = field.OriginalName ?? field.Name;
- string exceptionMessage;
+ StringBuilder exceptionMessage = new();
- if (indexType.IsStatic())
- {
- exceptionMessage =
- $"The value of '{fieldName}' field is a complex object. Indexing it as a text isn't supported and it's supposed to have \\\"Indexing\\\" option set to \\\"No\\\". " +
- $"Note that you can still store it and use it in projections.{Environment.NewLine}" +
- "If you need to use it for searching purposes, you have to call ToString() on the field value in the index definition.";
- }
- else
+ exceptionMessage.AppendLine(
+ $"The value of '{fieldName}' field is a complex object. Typically a complex field is not intended to be indexed as as whole hence indexing it as a text isn't supported in Corax. " +
+ $"The field is supposed to have 'Indexing' option set to 'No' (note that you can still store it and use it in projections). ");
+
+ if (indexVersion >= IndexDefinitionBaseServerSide.IndexVersion.CoraxComplexFieldIndexingBehavior)
{
- exceptionMessage =
- $"The value of '{fieldName}' field is a complex object. Indexing it as a text isn't supported. You should consider querying on individual fields of that object.";
+ exceptionMessage.AppendLine(
+ $"Alternatively you can switch '{RavenConfiguration.GetKey(x => x.Indexing.CoraxStaticIndexComplexFieldIndexingBehavior)}' configuration option from " +
+ $"'{CoraxComplexFieldIndexingBehavior.Throw}' to '{CoraxComplexFieldIndexingBehavior.Skip}' to disable the indexing of all complex fields in the index or globally for all indexes (index reset is required). ");
}
- throw new NotSupportedInCoraxException(exceptionMessage);
+
+ exceptionMessage.Append(
+ "If you really need to use this field for searching purposes, you have to call ToString() on the field value in the index definition. Although it's recommended to index individual fields of this complex object. " +
+ "Read more at: https://ravendb.net/l/OB9XW4/6.1");
+
+ throw new NotSupportedInCoraxException(exceptionMessage.ToString());
}
protected int AppendFieldValue(string field, object v, int index, TBuilder builder)
diff --git a/src/Raven.Server/NotificationCenter/Indexing.cs b/src/Raven.Server/NotificationCenter/Indexing.cs
index 89d46796083c..88ed3af9857d 100644
--- a/src/Raven.Server/NotificationCenter/Indexing.cs
+++ b/src/Raven.Server/NotificationCenter/Indexing.cs
@@ -252,7 +252,9 @@ private AlertRaised GetMismatchedReferencesAlert()
private AlertRaised GetComplexFieldAlert(ComplexFieldsWarning complexFieldsWarning)
{
- return AlertRaised.Create(_notificationCenter.Database, $"Complex field in Corax auto index", $"We have detected a complex field in an auto index. To avoid higher resources usage when processing JSON objects, the values of these fields will be replaced with 'JSON_VALUE'. Please consider querying on individual fields of that object or using a static index.", AlertType.Indexing_CoraxComplexItem, NotificationSeverity.Warning, Source, complexFieldsWarning);
+ return AlertRaised.Create(_notificationCenter.Database, $"Complex field in Corax auto index", $"We have detected a complex field in an auto index. " +
+ $"To avoid higher resources usage when processing JSON objects, the values of these fields will be replaced with 'JSON_VALUE'. " +
+ $"Please consider querying on individual fields of that object or using a static index. Read more at: https://ravendb.net/l/OB9XW4/6.1", AlertType.Indexing_CoraxComplexItem, NotificationSeverity.Warning, Source, complexFieldsWarning);
}
private AlertRaised GetCpuCreditsExhaustionAlert(CpuCreditsExhaustionWarning cpuCreditsExhaustionWarning)
diff --git a/src/Raven.Server/ServerWide/ServerStore.cs b/src/Raven.Server/ServerWide/ServerStore.cs
index d402da4c3cea..02c048812fb9 100644
--- a/src/Raven.Server/ServerWide/ServerStore.cs
+++ b/src/Raven.Server/ServerWide/ServerStore.cs
@@ -856,8 +856,8 @@ public void PreInitialize()
}
CheckSwapOrPageFileAndRaiseNotification();
-
-
+
+
LicenseManager.Initialize(_env, ContextPool);
LatestVersionCheck.Instance.Check(this);
}
diff --git a/src/Raven.Server/Web/Studio/EmbeddedData/Northwind.ravendbdump b/src/Raven.Server/Web/Studio/EmbeddedData/Northwind.ravendbdump
index c151e75c6718..2cd5c9b9bc7e 100644
Binary files a/src/Raven.Server/Web/Studio/EmbeddedData/Northwind.ravendbdump and b/src/Raven.Server/Web/Studio/EmbeddedData/Northwind.ravendbdump differ
diff --git a/src/Raven.Studio/typescript/models/database/index/configurationItem.ts b/src/Raven.Studio/typescript/models/database/index/configurationItem.ts
index bce252ac70f0..e8918fb33590 100644
--- a/src/Raven.Studio/typescript/models/database/index/configurationItem.ts
+++ b/src/Raven.Studio/typescript/models/database/index/configurationItem.ts
@@ -44,6 +44,7 @@ class configurationItem {
"Indexing.Corax.IncludeSpatialDistance",
"Indexing.Corax.MaxMemoizationSizeInMb",
"Indexing.Corax.MaxAllocationsAtDictionaryTrainingInMb",
+ "Indexing.Corax.Static.ComplexFieldIndexingBehavior"
// "Indexing.Static.SearchEngineType" - ignoring as we have dedicated widget to set that
/*
diff --git a/test/FastTests/Corax/Bugs/RavenDB-19442.cs b/test/FastTests/Corax/Bugs/RavenDB-19442.cs
index 46aee8ec5475..59ffd2e72ad1 100644
--- a/test/FastTests/Corax/Bugs/RavenDB-19442.cs
+++ b/test/FastTests/Corax/Bugs/RavenDB-19442.cs
@@ -1,5 +1,6 @@
using System.Linq;
using Raven.Client.Documents.Indexes;
+using Raven.Client.Documents.Operations.Indexes;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@@ -34,6 +35,7 @@ public void WhenIndexingFailedOnItemTheRestIsAlsoCorrupted(Options options)
session.Store(new TestData()
{
+ Complex = true,
Identifier = "hehe3",
Name = "a2",
Second = "b3"
@@ -42,20 +44,26 @@ public void WhenIndexingFailedOnItemTheRestIsAlsoCorrupted(Options options)
session.SaveChanges();
}
- new ComplexIndex().Execute(store);
- WaitForUserToContinueTheTest(store);
+ var index = new ComplexIndex();
+ index.Execute(store);
Indexes.WaitForIndexing(store);
+ var indexErrors = store.Maintenance.Send(new GetIndexErrorsOperation(new[] { index.IndexName }));
+ Assert.Equal(1, indexErrors.Length);
+
+ Assert.Contains("field is a complex object", indexErrors[0].Errors[0].Error);
using (var session = store.OpenSession())
{
var users = session
.Query()
.Customize(x => x.WaitForNonStaleResults())
- .Where(x => x.Identifier == "hehe3")
+ .Where(x => x.Identifier.StartsWith("hehe"))
.ToList();
- Assert.Equal(1, users.Count);
+ Assert.Equal(2, users.Count);
}
+
+ WaitForValue(() => store.Maintenance.Send(new GetIndexStatisticsOperation(index.IndexName)).EntriesCount, 2);
}
public class TestData
@@ -63,12 +71,13 @@ public class TestData
public string Name { get; set; }
public string Second { get; set; }
public string Identifier { get; set; }
+ public bool Complex { get; set; }
}
private class ComplexIndex : AbstractIndexCreationTask
{
public ComplexIndex()
{
- Map = datas => datas.Select(i => new { Identifier = i.Identifier, Complex = new { i.Name, i.Second } });
+ Map = datas => datas.Select(i => new { Identifier = i.Identifier, Complex = i.Complex ? new { i.Name, i.Second } : null });
Index("Complex", FieldIndexing.Exact);
}
diff --git a/test/FastTests/Issues/RavenDB_16590.cs b/test/FastTests/Issues/RavenDB_16590.cs
index a1bce2a3b5d9..213f253b35e1 100644
--- a/test/FastTests/Issues/RavenDB_16590.cs
+++ b/test/FastTests/Issues/RavenDB_16590.cs
@@ -87,6 +87,7 @@ public void StudioListsOfIndexScopedSettings()
"Indexing.Corax.IncludeSpatialDistance",
"Indexing.Corax.MaxMemoizationSizeInMb",
"Indexing.Corax.MaxAllocationsAtDictionaryTrainingInMb",
+ "Indexing.Corax.Static.ComplexFieldIndexingBehavior",
//Obsolete studio keys:
"Indexing.Static.SearchEngineType",
diff --git a/test/FastTests/Issues/RavenDB_21557.cs b/test/FastTests/Issues/RavenDB_21557.cs
index 869850b56f2b..a9841ac73743 100644
--- a/test/FastTests/Issues/RavenDB_21557.cs
+++ b/test/FastTests/Issues/RavenDB_21557.cs
@@ -3,6 +3,8 @@
using Raven.Client.Documents.Indexes;
using Raven.Client.Documents.Linq;
using Raven.Client.Documents.Queries;
+using Raven.Server.Config;
+using Raven.Server.Config.Categories;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@@ -112,6 +114,9 @@ public UserIndex()
};
StoreAllFields(FieldStorage.Yes);
+
+ Configuration[RavenConfiguration.GetKey(x => x.Indexing.CoraxStaticIndexComplexFieldIndexingBehavior)] =
+ IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Skip.ToString();
}
}
diff --git a/test/FastTests/Sharding/Queries/BasicShardedMapReduceQueryTests.cs b/test/FastTests/Sharding/Queries/BasicShardedMapReduceQueryTests.cs
index 544b9d18a977..92c08257ce55 100644
--- a/test/FastTests/Sharding/Queries/BasicShardedMapReduceQueryTests.cs
+++ b/test/FastTests/Sharding/Queries/BasicShardedMapReduceQueryTests.cs
@@ -1079,6 +1079,8 @@ group result by result.Freight into g
Freight = g.Key,
Lines = g.SelectMany(x => x.Lines).ToList()
};
+
+ Index(x => x.Lines, FieldIndexing.No);
}
}
diff --git a/test/SlowTests/Client/Indexing/Counters/BasicCountersIndexes_StrongSyntax.cs b/test/SlowTests/Client/Indexing/Counters/BasicCountersIndexes_StrongSyntax.cs
index 682f3dcbc2e1..9c7032932fd7 100644
--- a/test/SlowTests/Client/Indexing/Counters/BasicCountersIndexes_StrongSyntax.cs
+++ b/test/SlowTests/Client/Indexing/Counters/BasicCountersIndexes_StrongSyntax.cs
@@ -1383,7 +1383,7 @@ from result in results
into g
select new
{
- Value = g.Key,
+ Value = g.Key.Value,
Count = g.Sum(r => r.Count)
};
}
diff --git a/test/SlowTests/Corax/IndexSearcher.cs b/test/SlowTests/Corax/IndexSearcher.cs
index 184283f25b74..765691349ac4 100644
--- a/test/SlowTests/Corax/IndexSearcher.cs
+++ b/test/SlowTests/Corax/IndexSearcher.cs
@@ -144,6 +144,7 @@ private static void CreateEntry(IndexWriter indexWriter, IndexEntry entry)
builder.Write(ContentIndex, it[i]);
}
}
+ builder.EndWriting();
Span PrepareString(string value)
{
diff --git a/test/SlowTests/Corax/RavenDB-21430.cs b/test/SlowTests/Corax/RavenDB-21430.cs
index 2b255a6be995..f989f9490342 100644
--- a/test/SlowTests/Corax/RavenDB-21430.cs
+++ b/test/SlowTests/Corax/RavenDB-21430.cs
@@ -3,6 +3,7 @@
using FastTests;
using FastTests.Client;
using Raven.Client.Documents;
+using Raven.Client.Documents.Indexes;
using Raven.Client.Documents.Operations.Indexes;
using Raven.Server.NotificationCenter.Notifications;
using Tests.Infrastructure;
@@ -69,5 +70,47 @@ public async Task CanIndexComplexFieldInAutoIndex()
}
}
- private sealed record ComplexField(Query.Order Order, Query.Order Field, string Id = null);
+ [RavenFact(RavenTestCategory.Querying | RavenTestCategory.Indexes | RavenTestCategory.Corax)]
+ public async Task SearchComplexField()
+ {
+ using var store = GetDocumentStore(Options.ForSearchEngine(RavenSearchEngineMode.Corax));
+ using var session = store.OpenAsyncSession();
+ await session.StoreAsync(new ComplexField(new Query.Order() { Company = "Maciej" }, new Query.Order() { Company = "Test" }));
+ await session.StoreAsync(new ComplexField(null, null));
+ await session.SaveChangesAsync();
+
+ var index = new Index();
+ await index.ExecuteAsync(store);
+
+ var errors = await WaitForPredicateAsync(x => x.Length > 0 && x[0].Errors.Length > 0, () => store.Maintenance.SendAsync(new GetIndexErrorsOperation(new[] { index.IndexName })));
+ Assert.Equal(index.IndexName, errors[0].Name);
+ Assert.Contains("he value of 'Order' field is a complex object", errors[0].Errors[0].Error);
+ var result = await session.Query()
+ .Search(x => x.Order, "maciej")
+ .ToListAsync();
+ Assert.Equal(0, result.Count);
+ }
+
+ private sealed class Index : AbstractIndexCreationTask
+ {
+ public Index()
+ {
+ Map = fields => fields.Select(i => new { i.Order });
+ Index(x => x.Order, FieldIndexing.Search);
+ }
+ }
+
+ private sealed class ComplexField(Query.Order Order, Query.Order Field, string Id = null)
+ {
+ public Query.Order Order { get; init; } = Order;
+ public Query.Order Field { get; init; } = Field;
+ public string Id { get; init; } = Id;
+
+ public void Deconstruct(out Query.Order Order, out Query.Order Field, out string Id)
+ {
+ Order = this.Order;
+ Field = this.Field;
+ Id = this.Id;
+ }
+ }
}
diff --git a/test/SlowTests/Corax/RavenDB-21689.cs b/test/SlowTests/Corax/RavenDB-21689.cs
index afe3251c780a..3b86fe7d4dbb 100644
--- a/test/SlowTests/Corax/RavenDB-21689.cs
+++ b/test/SlowTests/Corax/RavenDB-21689.cs
@@ -46,7 +46,7 @@ public void NotAcceleratedAndWithInsideSetTermMatchWillNotHaveInfinityLoop()
builder.Write(0, Encodings.Utf8.GetBytes($"doc/{docIdx}"));
builder.Write(1, Encodings.Utf8.GetBytes("false"));
builder.Write(2, Encodings.Utf8.GetBytes($"abc{docIdx}"));
-
+ builder.EndWriting();
}
indexWriter.Commit();
diff --git a/test/SlowTests/Data/RavenDB_22534/RavenDB_22534.ravendb-snapshot b/test/SlowTests/Data/RavenDB_22534/RavenDB_22534.ravendb-snapshot
new file mode 100644
index 000000000000..4e47d6105693
Binary files /dev/null and b/test/SlowTests/Data/RavenDB_22534/RavenDB_22534.ravendb-snapshot differ
diff --git a/test/SlowTests/Issues/RavenDB-10995.cs b/test/SlowTests/Issues/RavenDB-10995.cs
index 7c7e5d45304d..89668c95f6b5 100644
--- a/test/SlowTests/Issues/RavenDB-10995.cs
+++ b/test/SlowTests/Issues/RavenDB-10995.cs
@@ -52,6 +52,8 @@ public PersonIndex()
}
};
StoresStrings.Add(Constants.Documents.Indexing.Fields.AllFields, FieldStorage.Yes);
+
+ Index(x => x.Pet, FieldIndexing.No);
}
}
diff --git a/test/SlowTests/Issues/RavenDB-14797.cs b/test/SlowTests/Issues/RavenDB-14797.cs
index 7d6a36db844b..a1beebd45b73 100644
--- a/test/SlowTests/Issues/RavenDB-14797.cs
+++ b/test/SlowTests/Issues/RavenDB-14797.cs
@@ -204,9 +204,8 @@ public JavaIndex()
Fields = new Dictionary
{
- {
- Constants.Documents.Indexing.Fields.AllFields, new IndexFieldOptions { Storage = FieldStorage.Yes }
- }
+ { Constants.Documents.Indexing.Fields.AllFields, new IndexFieldOptions { Storage = FieldStorage.Yes } },
+ { "Communication", new IndexFieldOptions() { Storage = FieldStorage.Yes, Indexing = FieldIndexing.No } }
};
}
}
@@ -255,6 +254,9 @@ public JavaWithAdditionalSourcesIndex()
return communications;
}"
};
+
+ Fields ??= new();
+ Fields.Add("Communications", new IndexFieldOptions() { Storage = FieldStorage.Yes, Indexing = FieldIndexing.No });
}
}
diff --git a/test/SlowTests/Issues/RavenDB-15298.cs b/test/SlowTests/Issues/RavenDB-15298.cs
index 20568bf36f5a..d44db0a717e3 100644
--- a/test/SlowTests/Issues/RavenDB-15298.cs
+++ b/test/SlowTests/Issues/RavenDB-15298.cs
@@ -29,12 +29,23 @@ public void Can_create_index_using_crete_field_on_dates(Options options)
{
@"from e in docs.Employees
select new {
- a = e.Select(x=>CreateField(x.Key, x.Value))
+ _ = e.Select(x=> {
+ if (x.Key == ""@metadata"")
+ return null;
+
+ if (x.Key == ""Address"")
+ return x.Value.Select(y => CreateField(""Address_"" + y.Key, y.Value.ToString()));
+
+ return CreateField(x.Key, x.Value);
+ })
}"
}
}));
Indexes.WaitForIndexing(store);
+
+ WaitForUserToContinueTheTest(store);
+
var statistics = store.Maintenance.Send(new GetStatisticsOperation());
Assert.Equal(IndexState.Normal, statistics.Indexes.Single(x => x.Name == "index").State);
diff --git a/test/SlowTests/Issues/RavenDB-16031.cs b/test/SlowTests/Issues/RavenDB-16031.cs
index d8c4669a9b63..19662c33e70c 100644
--- a/test/SlowTests/Issues/RavenDB-16031.cs
+++ b/test/SlowTests/Issues/RavenDB-16031.cs
@@ -31,7 +31,7 @@ public void ShouldWork(Options options)
using (var session = store.OpenSession())
{
var results = session.Query()
- .OrderBy(x=>x.d)
+ .OrderBy(x => x.d)
.ProjectInto().ToList();
Assert.Equal(3, results.Count);
Assert.NotNull(results[0].ac);
@@ -151,7 +151,8 @@ public Index_TestGrouping4()
{
{
Constants.Documents.Indexing.Fields.AllFields, new IndexFieldOptions { Storage = FieldStorage.Yes }
- }
+ },
+ { "a", new IndexFieldOptions() { Indexing = FieldIndexing.No }}
};
}
}
diff --git a/test/SlowTests/Issues/RavenDB-17097.cs b/test/SlowTests/Issues/RavenDB-17097.cs
index f4168f2c1084..1bf323477ce7 100644
--- a/test/SlowTests/Issues/RavenDB-17097.cs
+++ b/test/SlowTests/Issues/RavenDB-17097.cs
@@ -82,7 +82,12 @@ from documentItself in collectionDocuments
from inn in documentItself.Inners
let x = 1
let z = 2
- select new {Inner = inn, xx = x, zz = z, _ = CreateField("SourceDoc", documentItself)};
+ select new {Inner = inn, xx = x, zz = z, _ = CreateField("SourceDoc", documentItself, new() { Indexing = FieldIndexing.No, Storage = FieldStorage.Yes }) };
+
+ Index("Inner", FieldIndexing.No);
+ Index("SourceDoc", FieldIndexing.No);
+ Store("Inner", FieldStorage.Yes);
+ Store("SourceDoc", FieldStorage.Yes);
}
}
@@ -96,6 +101,11 @@ from inn in documentItself.Inners
let x = 1
let z = 2
select new {Field = documentItself, Inner = inn, xx = x, zz = z};
+
+ Index("Inner", FieldIndexing.No);
+ Index("Field", FieldIndexing.No);
+ Store("Inner", FieldStorage.Yes);
+ Store("Field", FieldStorage.Yes);
}
}
diff --git a/test/SlowTests/Issues/RavenDB-22523.cs b/test/SlowTests/Issues/RavenDB-22523.cs
index 3fee23e114af..df34cf2944d1 100644
--- a/test/SlowTests/Issues/RavenDB-22523.cs
+++ b/test/SlowTests/Issues/RavenDB-22523.cs
@@ -261,6 +261,9 @@ public TestDocumentCoraxIndex()
Map = docs => from doc in docs
select new { doc.Account, doc.Amount, doc.Tags, TagIds = Enumerable.ToArray(doc.Tags.Select(x => x.Id)) };
SearchEngineType = Raven.Client.Documents.Indexes.SearchEngineType.Corax;
+
+ Index(x => x.Tags, FieldIndexing.No);
+ Store(x => x.Tags, FieldStorage.Yes);
}
}
@@ -271,6 +274,9 @@ public TestDocumentLuceneIndex()
Map = docs => from doc in docs
select new { doc.Account, doc.Amount, doc.Tags, TagIds = Enumerable.ToArray(doc.Tags.Select(x => x.Id)) };
SearchEngineType = Raven.Client.Documents.Indexes.SearchEngineType.Lucene;
+
+ Index(x => x.Tags, FieldIndexing.No);
+ Store(x => x.Tags, FieldStorage.Yes);
}
}
}
diff --git a/test/SlowTests/Issues/RavenDB_16850.cs b/test/SlowTests/Issues/RavenDB_16850.cs
index c04fa8e653dc..2f9d42d222f7 100644
--- a/test/SlowTests/Issues/RavenDB_16850.cs
+++ b/test/SlowTests/Issues/RavenDB_16850.cs
@@ -2,6 +2,7 @@
using System.Linq;
using FastTests;
using Orders;
+using Raven.Client.Documents.Indexes;
using Raven.Client.Documents.Indexes.TimeSeries;
using Sparrow.Extensions;
using Tests.Infrastructure;
@@ -75,6 +76,9 @@ from segment in segments
{
Hours = hours
});
+
+ Index("Hours", FieldIndexing.No);
+ Store("Hours", FieldStorage.Yes);
}
}
}
diff --git a/test/SlowTests/Issues/RavenDB_18357.cs b/test/SlowTests/Issues/RavenDB_18357.cs
index f2abf556a5a9..ce1f2bd8bf7c 100644
--- a/test/SlowTests/Issues/RavenDB_18357.cs
+++ b/test/SlowTests/Issues/RavenDB_18357.cs
@@ -14,24 +14,6 @@ public class RavenDB_18357 : RavenTestBase
public RavenDB_18357(ITestOutputHelper output) : base(output)
{
}
-
- [RavenTheory(RavenTestCategory.Querying | RavenTestCategory.Indexes | RavenTestCategory.Corax)]
- [RavenData(SearchEngineMode = RavenSearchEngineMode.All)]
- public void StaticIndexShouldNotThrowWhenTryingToIndexComplexObjectAndIndexFieldOptionsWereNotExplicitlySetInDefinition(Options options)
- {
- using var store = GetDocumentStore(options);
- {
- using var s = store.OpenSession();
- s.Store(new Input {Nested = new NestedItem {Name = "Matt"}});
- s.SaveChanges();
- }
- var index = new InputIndex();
-
- index.Execute(store);
- Indexes.WaitForIndexing(store);
- var errors = Indexes.WaitForIndexingErrors(store, errorsShouldExists: false);
- Assert.Null(errors);
- }
[RavenTheory(RavenTestCategory.Querying | RavenTestCategory.Indexes | RavenTestCategory.Corax)]
[RavenData(SearchEngineMode = RavenSearchEngineMode.Corax)]
diff --git a/test/SlowTests/Issues/RavenDB_19546.cs b/test/SlowTests/Issues/RavenDB_19546.cs
index 1b9c4c98283e..fa3623ed8ce3 100644
--- a/test/SlowTests/Issues/RavenDB_19546.cs
+++ b/test/SlowTests/Issues/RavenDB_19546.cs
@@ -207,6 +207,8 @@ into g
};
OutputReduceToCollection = "UserAndUserAuthDetails";
+
+ Index(x => x.UserAuthDetailIds, FieldIndexing.No);
}
}
@@ -258,6 +260,8 @@ public UserAndUserAuthDetails_JavascriptIndex()
})";
OutputReduceToCollection = "UserClaims";
+
+ Fields = new Dictionary() { { "ClaimsPerProvider", new IndexFieldOptions() { Indexing = FieldIndexing.No } } };
}
}
diff --git a/test/SlowTests/Issues/RavenDB_22406.cs b/test/SlowTests/Issues/RavenDB_22406.cs
index 634587435db7..13458ae9d99e 100644
--- a/test/SlowTests/Issues/RavenDB_22406.cs
+++ b/test/SlowTests/Issues/RavenDB_22406.cs
@@ -15,7 +15,7 @@ public RavenDB_22406(ITestOutputHelper output) : base(output)
}
[RavenTheory(RavenTestCategory.Indexes)]
- [RavenData(SearchEngineMode = RavenSearchEngineMode.Lucene)]
+ [RavenData(SearchEngineMode = RavenSearchEngineMode.All)]
public void CanIndexProperlyWithOneInvalidDocument(Options options)
{
using var store = GetDocumentStore(options);
diff --git a/test/SlowTests/Issues/RavenDB_22534.cs b/test/SlowTests/Issues/RavenDB_22534.cs
new file mode 100644
index 000000000000..3a9e9e79785c
--- /dev/null
+++ b/test/SlowTests/Issues/RavenDB_22534.cs
@@ -0,0 +1,160 @@
+using System;
+using System.IO;
+using System.Linq;
+using FastTests;
+using Raven.Client.Documents.Indexes;
+using Raven.Client.Documents.Operations;
+using Raven.Client.Documents.Operations.Backups;
+using Raven.Client.Documents.Operations.Indexes;
+using Raven.Client.Documents.Smuggler;
+using Raven.Server.Config;
+using Raven.Server.Config.Categories;
+using Tests.Infrastructure;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace SlowTests.Issues;
+
+public class RavenDB_22534 : RavenTestBase
+{
+ public RavenDB_22534(ITestOutputHelper output) : base(output)
+ {
+ }
+
+ [RavenFact(RavenTestCategory.Indexes | RavenTestCategory.Corax)]
+ public void BackwardCompatibilityComplexFields()
+ {
+ var backupPath = NewDataPath(forceCreateDir: true);
+ var file = Path.Combine(backupPath, "RavenDB_22534.ravendb-snapshot");
+ ExtractFile(file);
+
+ var restoredDb = GetDatabaseName() + "_restored";
+ using var store = GetDocumentStore(Options.ForSearchEngine(RavenSearchEngineMode.Corax));
+ using var _ = Backup.RestoreDatabase(store, new RestoreBackupConfiguration { BackupLocation = backupPath, DatabaseName = restoredDb });
+
+ using (var session = store.OpenSession(restoredDb))
+ {
+ session.Advanced.WaitForIndexesAfterSaveChanges();
+ var index = new Index();
+ session.Store(new Dto() { Id = "doc3", DtoInner = new DtoInner() { Name = "3inner" } });
+ session.SaveChanges();
+ Indexes.WaitForIndexing(store, databaseName: restoredDb);
+
+ // no indexing errors after the restore and adding new document
+ // legacy indexing behavior should be applied
+ var indexErrors = store.Maintenance.ForDatabase(restoredDb).Send(new GetIndexErrorsOperation([index.IndexName, "Auto/Dtos/ByDtoInner"]));
+ Assert.Equal(2, indexErrors.Length);
+ Assert.Equal(0, indexErrors[0].Errors.Length);
+ Assert.Equal(0, indexErrors[1].Errors.Length);
+
+ // after index resets there are indexing errors on static index and no indexing errors on auto index
+ store.Maintenance.ForDatabase(restoredDb).Send(new ResetIndexOperation(index.IndexName, indexResetMode: IndexResetMode.InPlace));
+ store.Maintenance.ForDatabase(restoredDb).Send(new ResetIndexOperation("Auto/Dtos/ByDtoInner", indexResetMode: IndexResetMode.InPlace));
+ Indexes.WaitForIndexing(store, databaseName: restoredDb, allowErrors: true);
+ indexErrors = store.Maintenance.ForDatabase(restoredDb).Send(new GetIndexErrorsOperation([index.IndexName, "Auto/Dtos/ByDtoInner"]));
+ try
+ {
+ Assert.Equal(3, indexErrors[0].Errors.Length);
+ }
+ catch (Exception e)
+ {
+ WaitForUserToContinueTheTest(store, database: restoredDb);
+
+ Console.WriteLine(e);
+ throw;
+ }
+ Assert.Contains("https://ravendb.net/l/OB9XW4/6.1", indexErrors[0].Errors[0].Error);
+ Assert.Equal(0, indexErrors[1].Errors.Length);
+
+ // force skipping indexing of complex fields
+ index = new Index(complexFieldIndexingBehavior: IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Skip);
+ index.Execute(store, database: restoredDb);
+
+ Indexes.WaitForIndexing(store, databaseName: restoredDb, allowErrors: true); // errors come from current static index, while we're replacing it by the one that won't have any errors
+
+ indexErrors = store.Maintenance.ForDatabase(restoredDb).Send(new GetIndexErrorsOperation([index.IndexName]));
+ Assert.Equal(0, indexErrors[0].Errors.Length);
+
+ }
+ void ExtractFile(string path)
+ {
+ using (var fileStream = File.Create(path))
+ using (var stream = typeof(RavenDB_10404).Assembly.GetManifestResourceStream("SlowTests.Data.RavenDB_22534.RavenDB_22534.ravendb-snapshot"))
+ {
+ stream.CopyTo(fileStream);
+ }
+ }
+ }
+
+ private class Index : AbstractIndexCreationTask
+ {
+ public Index(IndexingConfiguration.CoraxComplexFieldIndexingBehavior? complexFieldIndexingBehavior = null)
+ {
+ Map = dtos => dtos.Select(x => new { x.DtoInner });
+
+ if (complexFieldIndexingBehavior != null)
+ {
+ Configuration[RavenConfiguration.GetKey(x => x.Indexing.CoraxStaticIndexComplexFieldIndexingBehavior)] =
+ complexFieldIndexingBehavior.ToString();
+ }
+ }
+ }
+
+ private class Dto
+ {
+ public string Id { get; set; }
+ public DtoInner DtoInner { get; set; }
+ }
+
+ private class DtoInner
+ {
+ public string Name { get; set; }
+ }
+
+ [RavenTheory(RavenTestCategory.Querying | RavenTestCategory.Indexes | RavenTestCategory.Corax)]
+ [RavenData(IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Skip, SearchEngineMode = RavenSearchEngineMode.Corax)]
+ [RavenData(IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Throw, SearchEngineMode = RavenSearchEngineMode.Corax)]
+ public void StaticCoraxIndexMustRespectComplexFieldIndexingBehavior(Options options, IndexingConfiguration.CoraxComplexFieldIndexingBehavior complexFieldIndexingBehavior)
+ {
+ using var store = GetDocumentStore(options);
+ {
+ using var s = store.OpenSession();
+ s.Store(new Dto() { DtoInner = new DtoInner() { Name = "inner" } });
+ s.SaveChanges();
+ }
+ var index = new Index(complexFieldIndexingBehavior);
+
+ index.Execute(store);
+ Indexes.WaitForIndexing(store, allowErrors: true);
+
+ if (complexFieldIndexingBehavior == IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Skip)
+ {
+ var errors = Indexes.WaitForIndexingErrors(store, errorsShouldExists: false);
+ Assert.Null(errors);
+ }
+ else
+ {
+ var errors = Indexes.WaitForIndexingErrors(store, errorsShouldExists: true);
+ Assert.Equal(1, errors[0].Errors.Length);
+ }
+ }
+
+ [RavenTheory(RavenTestCategory.Indexes)]
+ [RavenData(SearchEngineMode = RavenSearchEngineMode.All)]
+ public void SampleDataIndexesShouldNotIndexComplexFields(Options options)
+ {
+ using var store = GetDocumentStore(options);
+ store.Maintenance.Send(new CreateSampleDataOperation(DatabaseItemType.Documents | DatabaseItemType.Indexes | DatabaseItemType.CounterGroups));
+
+ Indexes.WaitForIndexing(store);
+
+ WaitForUserToContinueTheTest(store);
+
+ var indexErrors = store.Maintenance.Send(new GetIndexErrorsOperation());
+
+ foreach (var errors in indexErrors)
+ {
+ Assert.Empty(errors.Errors);
+ }
+ }
+}
diff --git a/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults.cs b/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults.cs
index 7b5d3661bab9..7c2d85dcb50c 100644
--- a/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults.cs
+++ b/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults.cs
@@ -46,11 +46,10 @@ public AccItems_Spatial()
from i in items
select new
{
- i,
Distance = CreateSpatialField((double)i.Lat, (double)i.Lon),
i.Name,
i.Bedrooms,
- i.Attributes
+ Attributes = i.Attributes.Select(x => x.ToString())
};
}
}
@@ -63,7 +62,7 @@ public AccItems_Attributes()
from i in items
select new
{
- i.Attributes
+ Attributes = i.Attributes.Select(x => x.ToString())
};
}
}
diff --git a/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults2.cs b/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults2.cs
index 81eec804d053..450c6a3d314d 100644
--- a/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults2.cs
+++ b/test/SlowTests/MailingList/CanRetrieveFacetCountsOfQueryResults2.cs
@@ -45,11 +45,10 @@ public AccItems_Spatial()
from i in items
select new
{
- i,
Distance = CreateSpatialField((double)i.Lat, (double)i.Lon),
i.Name,
i.Bedrooms,
- i.Attributes
+ Attributes = i.Attributes.Select(x => x.ToString())
};
}
}
@@ -62,7 +61,7 @@ public AccItems_Attributes()
from i in items
select new
{
- i.Attributes
+ Attributes = i.Attributes.Select(x => x.ToString())
};
}
}
diff --git a/test/SlowTests/MailingList/DataSetIndexTest.cs b/test/SlowTests/MailingList/DataSetIndexTest.cs
index 2570d0f7b341..6e70d0c7a703 100644
--- a/test/SlowTests/MailingList/DataSetIndexTest.cs
+++ b/test/SlowTests/MailingList/DataSetIndexTest.cs
@@ -5,6 +5,8 @@
using FastTests;
using Raven.Client.Documents.Indexes;
using Raven.Client.Documents.Session;
+using Raven.Server.Config;
+using Raven.Server.Config.Categories;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@@ -186,6 +188,10 @@ into g
{ e=>e.Attributes, FieldStorage.Yes},
{ e=>e.StationId, FieldStorage.Yes}
};
+
+ Configuration[RavenConfiguration.GetKey(x => x.Indexing.CoraxStaticIndexComplexFieldIndexingBehavior)] =
+ IndexingConfiguration.CoraxComplexFieldIndexingBehavior.Skip.ToString();
+
}
}
diff --git a/test/SlowTests/MailingList/ItemsBySetIdIndexTests.cs b/test/SlowTests/MailingList/ItemsBySetIdIndexTests.cs
index d9cc4274e1b4..4d9f06ac61ca 100644
--- a/test/SlowTests/MailingList/ItemsBySetIdIndexTests.cs
+++ b/test/SlowTests/MailingList/ItemsBySetIdIndexTests.cs
@@ -4,6 +4,8 @@
using System.Linq.Expressions;
using FastTests;
using Raven.Client.Documents.Indexes;
+using Raven.Server.Config;
+using Raven.Server.Config.Categories;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@@ -189,6 +191,8 @@ public ItemsBySetIdIndex()
{ e=>e.LastTestDate, FieldStorage.Yes},
{ e=>e.LastTestId, FieldStorage.Yes}
};
+
+ Index(x => x.Attributes, FieldIndexing.No);
}
}
diff --git a/test/SlowTests/SlowTests.csproj b/test/SlowTests/SlowTests.csproj
index c5e2f854b002..9b1c4212fc9e 100644
--- a/test/SlowTests/SlowTests.csproj
+++ b/test/SlowTests/SlowTests.csproj
@@ -48,6 +48,7 @@
+
@@ -137,6 +138,7 @@
+
diff --git a/test/SlowTests/Tests/Linq/OfTypeSuppor3.cs b/test/SlowTests/Tests/Linq/OfTypeSuppor3.cs
index a7c5063c952f..f40db44af83a 100644
--- a/test/SlowTests/Tests/Linq/OfTypeSuppor3.cs
+++ b/test/SlowTests/Tests/Linq/OfTypeSuppor3.cs
@@ -8,6 +8,8 @@
using FastTests;
using Raven.Client.Documents;
using Raven.Client.Documents.Indexes;
+using Raven.Server.Config;
+using Raven.Server.Config.Categories;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;
@@ -43,6 +45,7 @@ public void OfTypeSupportSelectAfterwards(Options options)
.Single();
Assert.NotNull(item.Strings);
+ Assert.NotNull(item.Values);
}
}
}
@@ -64,6 +67,9 @@ public Index()
});
Store(result => result.Strings, FieldStorage.Yes);
+
+ Store(x => x.Values, FieldStorage.Yes);
+ Index(x => x.Values, FieldIndexing.No);
}
}