From 983c0d7e3a096a9bb4951aad4c6d4ffe4e139e41 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Sat, 19 Oct 2024 00:24:49 -0700 Subject: [PATCH 01/10] Initial code changes to introduce full text search. --- .../src/Fluent/Settings/ContainerBuilder.cs | 28 ++++++ .../Settings/FullTextIndexDefinition.cs | 65 ++++++++++++++ .../Settings/FullTextPolicyDefinition.cs | 58 +++++++++++++ .../Settings/IndexingPolicyDefinition.cs | 21 +++++ .../Resource/Settings/ContainerProperties.cs | 29 +++++++ .../Resource/Settings/FullTextIndexPath.cs | 61 +++++++++++++ .../src/Resource/Settings/FullTextPath.cs | 87 +++++++++++++++++++ .../src/Resource/Settings/FullTextPolicy.cs | 71 +++++++++++++++ .../src/Resource/Settings/IndexingPolicy.cs | 27 ++++++ .../Settings/VectorEmbeddingPolicy.cs | 2 +- 10 files changed, 448 insertions(+), 1 deletion(-) create mode 100644 Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs create mode 100644 Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs create mode 100644 Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs index 6b6f5e73cb..01bcb7e021 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs @@ -23,6 +23,7 @@ public class ContainerBuilder : ContainerDefinition private ChangeFeedPolicy changeFeedPolicy; private ClientEncryptionPolicy clientEncryptionPolicy; private VectorEmbeddingPolicy vectorEmbeddingPolicy; + private FullTextPolicy fullTextPolicy; /// /// Creates an instance for unit-testing @@ -136,6 +137,28 @@ VectorEmbeddingPolicyDefinition WithVectorEmbeddingPolicy( (embeddingPolicy) => this.AddVectorEmbeddingPolicy(embeddingPolicy)); } + /// + /// Defined the vector embedding policy for this Azure Cosmos container + /// + /// blablan. + /// List of vector embeddings to include in the policy definition. + /// An instance of . +#if PREVIEW + public +#else + internal +#endif + FullTextPolicyDefinition WithFullTextPolicy( + string defaultLanguage, + Collection fullTextPaths) + { + return new FullTextPolicyDefinition( + this, + defaultLanguage, + fullTextPaths, + (fullTextPolicy) => this.AddFullTextSearchPolicy(fullTextPolicy)); + } + /// /// Creates a container with the current fluent definition. /// @@ -286,5 +309,10 @@ private void AddVectorEmbeddingPolicy(VectorEmbeddingPolicy embeddingPolicy) { this.vectorEmbeddingPolicy = embeddingPolicy; } + + private void AddFullTextSearchPolicy(FullTextPolicy fullTextPolicy) + { + this.fullTextPolicy = fullTextPolicy; + } } } diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs new file mode 100644 index 0000000000..d84244011b --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs @@ -0,0 +1,65 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Fluent +{ + using System; + + /// + /// Full Text index fluent definition. + /// + /// +#if PREVIEW + public +#else + internal +#endif + class FullTextIndexDefinition + { + private readonly FullTextIndexPath fullTextIndexPath = new (); + private readonly T parent; + private readonly Action attachCallback; + + /// + /// Initializes a new instance of the class. + /// + /// The original instance of . + /// A callback delegate to be used at a later point of time. + public FullTextIndexDefinition( + T parent, + Action attachCallback) + { + this.parent = parent; + this.attachCallback = attachCallback; + } + + /// + /// Add a path to the current definition. + /// + /// Property path for the current definition. Example: /property + /// An instance of the current . + public FullTextIndexDefinition Path( + string path) + { + if (string.IsNullOrEmpty(path)) + { + throw new ArgumentNullException(nameof(path)); + } + + this.fullTextIndexPath.Path = path; + + return this; + } + + /// + /// Applies the current definition to the parent. + /// + /// An instance of the parent. + public T Attach() + { + this.attachCallback(this.fullTextIndexPath); + return this.parent; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs new file mode 100644 index 0000000000..aa04158798 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs @@ -0,0 +1,58 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos.Fluent +{ + using System; + using System.Collections.ObjectModel; + + /// + /// fluent definition. + /// +#if PREVIEW + public +#else + internal +#endif + class FullTextPolicyDefinition + { + private readonly ContainerBuilder parent; + private readonly Action attachCallback; + private readonly string defaultLanguage; + private readonly Collection fullTextPaths; + + /// + /// Initializes a new instance of the class. + /// + /// The original instance of . + /// blabla + /// List of fullTextPaths to include in the policy definition. + /// A callback delegate to be used at a later point of time. + public FullTextPolicyDefinition( + ContainerBuilder parent, + string defaultLanguage, + Collection fullTextPaths, + Action attachCallback) + { + this.parent = parent ?? throw new ArgumentNullException(nameof(parent)); + this.attachCallback = attachCallback ?? throw new ArgumentNullException(nameof(attachCallback)); + this.fullTextPaths = fullTextPaths; + this.defaultLanguage = defaultLanguage; + } + + /// + /// Applies the current definition to the parent. + /// + /// An instance of the parent. + public ContainerBuilder Attach() + { + FullTextPolicy fullTextPolicy = new ( + this.defaultLanguage, + this.fullTextPaths); + + this.attachCallback(fullTextPolicy); + return this.parent; + } + } +} diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs index 3800e8c8a7..b87e4d3cd3 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs @@ -129,6 +129,22 @@ VectorIndexDefinition> WithVectorIndex() (vectorIndex) => this.AddVectorIndexPath(vectorIndex)); } + /// + /// Defines a in the current 's definition. + /// + /// An instance of . +#if PREVIEW + public +#else + internal +#endif + FullTextIndexDefinition> WithFullTextIndex() + { + return new FullTextIndexDefinition>( + this, + (fullTextIndex) => this.AddFullTextndexPath(fullTextIndex)); + } + /// /// Applies the current definition to the parent. /// @@ -154,6 +170,11 @@ private void AddVectorIndexPath(VectorIndexPath vectorIndexPath) this.indexingPolicy.VectorIndexes.Add(vectorIndexPath); } + private void AddFullTextndexPath(FullTextIndexPath fullTextIndexPath) + { + this.indexingPolicy.FullTextIndexes.Add(fullTextIndexPath); + } + private void AddIncludedPaths(IEnumerable paths) { foreach (string path in paths) diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs index fea8747a79..f8af8b5b7d 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs @@ -84,6 +84,9 @@ public class ContainerProperties [JsonProperty(PropertyName = "computedProperties", NullValueHandling = NullValueHandling.Ignore)] private Collection computedProperties; + [JsonProperty(PropertyName = "fullTextPolicy", NullValueHandling = NullValueHandling.Ignore)] + private FullTextPolicy fullTextPolicyInternal; + /// /// This contains additional values for scenarios where the SDK is not aware of new fields. /// This ensures that if resource is read and updated none of the fields will be lost in the process. @@ -360,6 +363,32 @@ Collection ComputedProperties } } + /// + /// Gets or sets the full text policy containing paths for full text paths along with path-specific settings for the item + /// used in performing full text search on the items in a collection in the Azure CosmosDB database service. + /// + /// + /// It is an optional property. + /// By default, FullTextPolicy is set to null meaning the feature is turned off for the container. + /// + /// + /// + /// The will be applied to all the items in the container as the default policy. + /// + /// + [JsonIgnore] +#if PREVIEW + public +#else + internal +#endif + FullTextPolicy FullTextPolicy + { + get => this.fullTextPolicyInternal; + + set => this.fullTextPolicyInternal = value; + } + /// /// Gets the associated with the container from the Azure Cosmos DB service. /// diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs new file mode 100644 index 0000000000..f79855c2bf --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs @@ -0,0 +1,61 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + using Microsoft.Azure.Documents; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + /// + /// DOM for a full text index path. A full text index path is used in a full text index. + /// + /// + /// + /// +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextIndexPath + { + /// + /// Gets or sets the full path in a document used for full text indexing. + /// + [JsonProperty(PropertyName = Constants.Properties.Path)] + public string Path { get; set; } + + /// + /// This contains additional values for scenarios where the SDK is not aware of new fields. + /// This ensures that if resource is read and updated none of the fields will be lost in the process. + /// + [JsonExtensionData] + internal IDictionary AdditionalProperties { get; private set; } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs new file mode 100644 index 0000000000..09cd6c8de1 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs @@ -0,0 +1,87 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +namespace Microsoft.Azure.Cosmos +{ + using System; + using System.Collections.Generic; + using Microsoft.Azure.Documents; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + /// + /// DOM for a full text index policy. A full text policy is defined at the collection level. + /// + /// + /// + /// +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextPath : IEquatable + { + /// + /// Gets or sets a string containing the path of the full text index. + /// + [JsonProperty(PropertyName = Constants.Properties.Path)] + public string Path { get; set; } + + /// + /// Gets or sets a string containing the language of the full text path. + /// + [JsonProperty(PropertyName = "language")] + public string Language { get; set; } + + /// + /// This contains additional values for scenarios where the SDK is not aware of new fields. + /// This ensures that if resource is read and updated none of the fields will be lost in the process. + /// + [JsonExtensionData] + internal IDictionary AdditionalProperties { get; private set; } + + /// + /// Ensures that the paths specified in the full text policy are valid. + /// + public void ValidateFullTextPath() + { + if (string.IsNullOrEmpty(this.Path)) + { + throw new ArgumentException("Argument {0} can't be null or empty.", nameof(this.Path)); + } + + if (string.IsNullOrEmpty(this.Language)) + { + throw new ArgumentException("Argument {0} can't be null or empty.", nameof(this.Language)); + } + + if (this.Path[0] != '/') + { + throw new ArgumentException("The argument {0} is not a valid path.", this.Path); + } + } + + /// + public bool Equals(FullTextPath that) + { + return this.Path.Equals(that.Path) && this.Language.Equals(that.Language); + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs new file mode 100644 index 0000000000..bea5efd551 --- /dev/null +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs @@ -0,0 +1,71 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ +namespace Microsoft.Azure.Cosmos +{ + using System.Collections.Generic; + using System.Collections.ObjectModel; + using Newtonsoft.Json; + using Newtonsoft.Json.Linq; + + /// + /// Represents the full text policy configuration for specifying the full text paths on documents in the collection in the Azure Cosmos DB service. + /// + /// +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextPolicy + { + /// + /// Initializes a new instance of the class. + /// + /// String of the default language of the container. + /// List of full text paths to include in the policy definition. + public FullTextPolicy( + string defaultLanguage, + Collection fullTextPaths) + { + if (fullTextPaths != null) + { + FullTextPolicy.ValidateFullTextPaths(fullTextPaths); + } + + this.DefaultLanguage = defaultLanguage; + this.FullTextPaths = fullTextPaths; + } + + /// + /// Gets or sets a string containing the default language of the container. + /// + [JsonProperty(PropertyName = "defaultLanguage", NullValueHandling = NullValueHandling.Ignore)] + public string DefaultLanguage { get; set; } + + /// + /// Gets a collection of that contains the full text paths of documents in collection in the Azure Cosmos DB service. + /// + [JsonProperty(PropertyName = "fullTextPaths", NullValueHandling = NullValueHandling.Ignore)] + public readonly Collection FullTextPaths; + + /// + /// This contains additional values for scenarios where the SDK is not aware of new fields. + /// This ensures that if resource is read and updated none of the fields will be lost in the process. + /// + [JsonExtensionData] + internal IDictionary AdditionalProperties { get; private set; } + + /// + /// Ensures that the specified full text paths in the policy are valid. + /// + private static void ValidateFullTextPaths( + IEnumerable fullTextPaths) + { + foreach (FullTextPath item in fullTextPaths) + { + item.ValidateFullTextPath(); + } + } + } +} \ No newline at end of file diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs index b8e0323b76..d06a5acf99 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs @@ -147,6 +147,33 @@ public IndexingPolicy() #endif Collection VectorIndexes { get; set; } = new Collection(); + /// + /// Gets the full text indexes + /// + /// + /// + /// + [JsonProperty(PropertyName = "fullTextIndexes", NullValueHandling = NullValueHandling.Ignore)] +#if PREVIEW + + public +#else + internal +#endif + Collection FullTextIndexes{ get; set; } = new Collection(); + /// /// This contains additional values for scenarios where the SDK is not aware of new fields. /// This ensures that if resource is read and updated none of the fields will be lost in the process. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs index 40db04fca9..431ae2915c 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs @@ -33,7 +33,7 @@ public VectorEmbeddingPolicy(Collection embeddings) /// /// Gets a collection of that contains the vector embeddings of documents in collection in the Azure Cosmos DB service. /// - [JsonProperty(PropertyName = "vectorEmbeddings")] + [JsonProperty(PropertyName = "fullTextPaths")] public readonly Collection Embeddings; /// From 8100f5f6a7058dc8a60b43c6703ff6cfbc1093bd Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 13:32:44 -0700 Subject: [PATCH 02/10] Code changes to add full text index tests. --- .../Settings/VectorEmbeddingPolicy.cs | 2 +- .../Fluent/ContainerSettingsTests.cs | 76 ++++++++++++++++++- .../CosmosContainerSettingsTests.cs | 62 +++++++++++++++ .../SettingsContractTests.cs | 72 +++++++++++++++++- 4 files changed, 208 insertions(+), 4 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs index 431ae2915c..40db04fca9 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/VectorEmbeddingPolicy.cs @@ -33,7 +33,7 @@ public VectorEmbeddingPolicy(Collection embeddings) /// /// Gets a collection of that contains the vector embeddings of documents in collection in the Azure Cosmos DB service. /// - [JsonProperty(PropertyName = "fullTextPaths")] + [JsonProperty(PropertyName = "vectorEmbeddings")] public readonly Collection Embeddings; /// diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs index a7ef72fece..7f654b9dd5 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs @@ -7,7 +7,6 @@ namespace Microsoft.Azure.Cosmos.SDK.EmulatorTests using Microsoft.VisualStudio.TestTools.UnitTesting; using Newtonsoft.Json.Linq; using System; - using System.Collections.Generic; using System.Collections.ObjectModel; using System.IO; using System.Linq; @@ -683,6 +682,81 @@ await this.database.DefineContainer(containerName, partitionKeyPath) Assert.AreEqual(HttpStatusCode.NoContent, containerResponse.StatusCode); } + [TestMethod] + //[Ignore("This test will be enabled once the full text search changes are made available into the public emulator.")] + public async Task TestFullTExtSearchPolicy() + { + string fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; + Database databaseForVectorEmbedding = await this.GetClient().CreateDatabaseAsync("fullTextSearchDB", + cancellationToken: this.cancellationToken); + + try + { + Collection fullTextPaths = new Collection() + { + new FullTextPath() + { + Path = fullTextPath1, + Language = "en-US", + }, + new FullTextPath() + { + Path = fullTextPath2, + Language = "en-US", + }, + new FullTextPath() + { + Path = fullTextPath3, + Language = "en-US", + }, + }; + + string containerName = "fullTextContainerTest"; + string partitionKeyPath = "/pk"; + + ContainerResponse containerResponse = + await databaseForVectorEmbedding.DefineContainer(containerName, partitionKeyPath) + .WithFullTextPolicy( + defaultLanguage: "en-US", + fullTextPaths: fullTextPaths) + .Attach() + .WithIndexingPolicy() + .WithFullTextIndex() + .Path(fullTextPath1) + .Attach() + .WithFullTextIndex() + .Path(fullTextPath2) + .Attach() + .WithFullTextIndex() + .Path(fullTextPath3) + .Attach() + .Attach() + .CreateAsync(); + + Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); + Assert.AreEqual(containerName, containerResponse.Resource.Id); + Assert.AreEqual(partitionKeyPath, containerResponse.Resource.PartitionKey.Paths.First()); + ContainerProperties containerSettings = containerResponse.Resource; + + // Validate FullText Paths. + Assert.IsNotNull(containerSettings.FullTextPolicy); + Assert.IsNotNull(containerSettings.FullTextPolicy.FullTextPaths); + Assert.AreEqual(fullTextPaths.Count, containerSettings.FullTextPolicy.FullTextPaths.Count()); + Assert.IsTrue(fullTextPaths.OrderBy(x => x.Path).SequenceEqual(containerSettings.FullTextPolicy.FullTextPaths.OrderBy(x => x.Path))); + + // Validate Full Text Indexes. + Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes); + Assert.AreEqual(fullTextPaths.Count, containerSettings.IndexingPolicy.FullTextIndexes.Count()); + Assert.AreEqual(fullTextPath1, containerSettings.IndexingPolicy.FullTextIndexes[0].Path); + Assert.AreEqual(fullTextPath2, containerSettings.IndexingPolicy.FullTextIndexes[1].Path); + Assert.AreEqual(fullTextPath1, containerSettings.IndexingPolicy.FullTextIndexes[2].Path); + } + finally + { + await databaseForVectorEmbedding.DeleteAsync(); + } + } + [Ignore] [TestMethod] public async Task WithComputedProperties() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs index 86b80fabe3..d7e87168bc 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs @@ -269,6 +269,68 @@ public void ValidateVectorEmbeddingsAndIndexes() CollectionAssert.AreEqual(new string[] { "/ZipCode" }, vectorIndexes[2].VectorIndexShardKey); } + [TestMethod] + public void ValidateFullTextPathsAndIndexes() + { + string defaultLanguage = "en-US", fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; + + Collection fullTextPaths = new Collection() + { + new Cosmos.FullTextPath() + { + Path = fullTextPath1, + Language = "en-US", + }, + new Cosmos.FullTextPath() + { + Path = fullTextPath2, + Language = "en-US", + }, + new Cosmos.FullTextPath() + { + Path = fullTextPath3, + Language = "en-US", + }, + }; + + ContainerProperties containerSettings = new ContainerProperties(id: "TestContainer", partitionKeyPath: "/partitionKey") + { + FullTextPolicy = new(defaultLanguage, fullTextPaths), + IndexingPolicy = new Cosmos.IndexingPolicy() + { + FullTextIndexes = new() + { + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath1, + }, + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath2, + }, + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath3, + } + }, + }, + }; + + Assert.IsNotNull(containerSettings.IndexingPolicy); + Assert.IsNotNull(containerSettings.FullTextPolicy); + Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes); + + Cosmos.FullTextPolicy fullTextPolicy = containerSettings.FullTextPolicy; + Assert.IsNotNull(fullTextPolicy.FullTextPaths); + Assert.AreEqual(fullTextPaths.Count, fullTextPolicy.FullTextPaths.Count()); + CollectionAssert.AreEquivalent(fullTextPaths, fullTextPolicy.FullTextPaths.ToList()); + + Collection fullTextIndexes = containerSettings.IndexingPolicy.FullTextIndexes; + Assert.AreEqual("/fts1", fullTextIndexes[0].Path); + Assert.AreEqual("/fts2", fullTextIndexes[1].Path); + Assert.AreEqual("/fts3", fullTextIndexes[2].Path); + } + private static string SerializeDocumentCollection(DocumentCollection collection) { using (MemoryStream ms = new MemoryStream()) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs index e01643dcb7..4e806c2205 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs @@ -339,7 +339,7 @@ public void AccountPropertiesDeserializeWithAdditionalDataTest() [TestMethod] public void ContainerPropertiesDeserializeWithAdditionalDataTest() { - string cosmosSerialized = "{\"indexingPolicy\":{\"automatic\":true,\"indexingMode\":\"Consistent\",\"additionalIndexPolicy\":\"indexpolicyvalue\",\"includedPaths\":[{\"path\":\"/included/path\",\"additionalIncludedPath\":\"includedPathValue\",\"indexes\":[]}],\"excludedPaths\":[{\"path\":\"/excluded/path\",\"additionalExcludedPath\":\"excludedPathValue\"}],\"compositeIndexes\":[[{\"path\":\"/composite/path\",\"additionalCompositeIndex\":\"compositeIndexValue\",\"order\":\"ascending\"}]],\"spatialIndexes\":[{\"path\":\"/spatial/path\",\"additionalSpatialIndexes\":\"spatialIndexValue\",\"types\":[]}],\"vectorIndexes\":[{\"path\":\"/vector1\",\"type\":\"flat\",\"additionalVectorIndex\":\"vectorIndexValue1\"},{\"path\":\"/vector2\",\"type\":\"quantizedFlat\",\"additionalVectorIndex\":\"vectorIndexValue2\"},{\"path\":\"/vector3\",\"type\":\"diskANN\"}]},\"computedProperties\":[{\"name\":\"lowerName\",\"query\":\"SELECT VALUE LOWER(c.name) FROM c\"},{\"name\":\"estimatedTax\",\"query\":\"SELECT VALUE c.salary * 0.2 FROM c\"}],\"geospatialConfig\":{\"type\":\"Geography\",\"additionalGeospatialConfig\":\"geospatialConfigValue\"},\"uniqueKeyPolicy\":{\"additionalUniqueKeyPolicy\":\"uniqueKeyPolicyValue\",\"uniqueKeys\":[{\"paths\":[\"/unique/key/path/1\",\"/unique/key/path/2\"]}]},\"conflictResolutionPolicy\":{\"mode\":\"LastWriterWins\",\"additionalConflictResolutionPolicy\":\"conflictResolutionValue\"},\"clientEncryptionPolicy\":{\"includedPaths\":[{\"path\":\"/path\",\"clientEncryptionKeyId\":\"clientEncryptionKeyId\",\"encryptionType\":\"Randomized\",\"additionalIncludedPath\":\"includedPathValue\",\"encryptionAlgorithm\":\"AEAD_AES_256_CBC_HMAC_SHA256\"}],\"policyFormatVersion\":1,\"additionalEncryptionPolicy\":\"clientEncryptionpolicyValue\"},\"id\":\"2a9f501b-6948-4795-8fd1-797defb5c466\",\"partitionKey\":{\"paths\":[],\"kind\":\"Hash\"},\"vectorEmbeddingPolicy\":{\"vectorEmbeddings\":[{\"path\":\"/vector1\",\"dataType\":\"float32\",\"dimensions\":1200,\"distanceFunction\":\"cosine\"},{\"path\":\"/vector2\",\"dataType\":\"int8\",\"dimensions\":3,\"distanceFunction\":\"dotproduct\"},{\"path\":\"/vector3\",\"dataType\":\"uint8\",\"dimensions\":400,\"distanceFunction\":\"euclidean\"}]}}"; + string cosmosSerialized = "{\"indexingPolicy\":{\"automatic\":true,\"indexingMode\":\"Consistent\",\"additionalIndexPolicy\":\"indexpolicyvalue\",\"includedPaths\":[{\"path\":\"/included/path\",\"additionalIncludedPath\":\"includedPathValue\",\"indexes\":[]}],\"excludedPaths\":[{\"path\":\"/excluded/path\",\"additionalExcludedPath\":\"excludedPathValue\"}],\"compositeIndexes\":[[{\"path\":\"/composite/path\",\"additionalCompositeIndex\":\"compositeIndexValue\",\"order\":\"ascending\"}]],\"spatialIndexes\":[{\"path\":\"/spatial/path\",\"additionalSpatialIndexes\":\"spatialIndexValue\",\"types\":[]}],\"vectorIndexes\":[{\"path\":\"/vector1\",\"type\":\"flat\",\"additionalVectorIndex\":\"vectorIndexValue1\"},{\"path\":\"/vector2\",\"type\":\"quantizedFlat\",\"additionalVectorIndex\":\"vectorIndexValue2\"},{\"path\":\"/vector3\",\"type\":\"diskANN\"}],\"fullTextIndexes\":[{\"path\":\"/fullTextPath1\",\"additionalFullTextIndex\":\"fullTextIndexValue1\"},{\"path\":\"/fullTextPath2\",\"additionalFullTextIndex\":\"fullTextIndexValue2\"},{\"path\":\"/fullTextPath3\"}]},\"computedProperties\":[{\"name\":\"lowerName\",\"query\":\"SELECT VALUE LOWER(c.name) FROM c\"},{\"name\":\"estimatedTax\",\"query\":\"SELECT VALUE c.salary * 0.2 FROM c\"}],\"geospatialConfig\":{\"type\":\"Geography\",\"additionalGeospatialConfig\":\"geospatialConfigValue\"},\"uniqueKeyPolicy\":{\"additionalUniqueKeyPolicy\":\"uniqueKeyPolicyValue\",\"uniqueKeys\":[{\"paths\":[\"/unique/key/path/1\",\"/unique/key/path/2\"]}]},\"conflictResolutionPolicy\":{\"mode\":\"LastWriterWins\",\"additionalConflictResolutionPolicy\":\"conflictResolutionValue\"},\"clientEncryptionPolicy\":{\"includedPaths\":[{\"path\":\"/path\",\"clientEncryptionKeyId\":\"clientEncryptionKeyId\",\"encryptionType\":\"Randomized\",\"additionalIncludedPath\":\"includedPathValue\",\"encryptionAlgorithm\":\"AEAD_AES_256_CBC_HMAC_SHA256\"}],\"policyFormatVersion\":1,\"additionalEncryptionPolicy\":\"clientEncryptionpolicyValue\"},\"id\":\"2a9f501b-6948-4795-8fd1-797defb5c466\",\"partitionKey\":{\"paths\":[],\"kind\":\"Hash\"},\"vectorEmbeddingPolicy\":{\"vectorEmbeddings\":[{\"path\":\"/vector1\",\"dataType\":\"float32\",\"dimensions\":1200,\"distanceFunction\":\"cosine\"},{\"path\":\"/vector2\",\"dataType\":\"int8\",\"dimensions\":3,\"distanceFunction\":\"dotproduct\"},{\"path\":\"/vector3\",\"dataType\":\"uint8\",\"dimensions\":400,\"distanceFunction\":\"euclidean\"}]},\"fullTextPolicy\": {\"defaultLanguage\": \"en-US\",\"fullTextPaths\": [{\"path\": \"/fullTextPath1\",\"language\": \"en-US\"},{\"path\": \"/fullTextPath2\",\"language\": \"en-US\"},{\"path\": \"/fullTextPath3\",\"language\": \"en-US\"}]}}"; JObject complexObject = JObject.FromObject(new { id = 1, name = new { fname = "fname", lname = "lname" } }); @@ -376,6 +376,12 @@ public void ContainerPropertiesDeserializeWithAdditionalDataTest() Assert.IsNull(containerProperties.IndexingPolicy.VectorIndexes[2].AdditionalProperties); + Assert.AreEqual(1, containerProperties.IndexingPolicy.FullTextIndexes[0].AdditionalProperties.Count); + Assert.AreEqual("fullTextIndexValue1", containerProperties.IndexingPolicy.FullTextIndexes[0].AdditionalProperties["additionalFullTextIndex"]); + + Assert.AreEqual(1, containerProperties.IndexingPolicy.FullTextIndexes[1].AdditionalProperties.Count); + Assert.AreEqual("fullTextIndexValue2", containerProperties.IndexingPolicy.FullTextIndexes[1].AdditionalProperties["additionalFullTextIndex"]); + Assert.AreEqual(1, containerProperties.IndexingPolicy.IncludedPaths[0].AdditionalProperties.Count); Assert.AreEqual("includedPathValue", containerProperties.IndexingPolicy.IncludedPaths[0].AdditionalProperties["additionalIncludedPath"]); @@ -404,6 +410,19 @@ public void ContainerPropertiesDeserializeWithAdditionalDataTest() Assert.AreEqual(1200, containerProperties.VectorEmbeddingPolicy.Embeddings[0].Dimensions); Assert.AreEqual(Cosmos.DistanceFunction.Cosine, containerProperties.VectorEmbeddingPolicy.Embeddings[0].DistanceFunction); + Assert.IsNotNull(containerProperties.FullTextPolicy); + Assert.AreEqual("en-US", containerProperties.FullTextPolicy.DefaultLanguage); + Assert.AreEqual(3, containerProperties.FullTextPolicy.FullTextPaths.Count); + + Assert.AreEqual("/fullTextPath1", containerProperties.FullTextPolicy.FullTextPaths[0].Path); + Assert.AreEqual("en-US", containerProperties.FullTextPolicy.FullTextPaths[0].Language); + + Assert.AreEqual("/fullTextPath2", containerProperties.FullTextPolicy.FullTextPaths[1].Path); + Assert.AreEqual("en-US", containerProperties.FullTextPolicy.FullTextPaths[1].Language); + + Assert.AreEqual("/fullTextPath3", containerProperties.FullTextPolicy.FullTextPaths[2].Path); + Assert.AreEqual("en-US", containerProperties.FullTextPolicy.FullTextPaths[2].Language); + Assert.AreEqual(2, containerProperties.ComputedProperties.Count); Assert.AreEqual("lowerName", containerProperties.ComputedProperties[0].Name); Assert.AreEqual("SELECT VALUE LOWER(c.name) FROM c", containerProperties.ComputedProperties[0].Query); @@ -805,7 +824,7 @@ public void ContainerSettingsDefaults() [TestMethod] public async Task ContainerSettingsIndexTest() { - string containerJsonString = "{\"indexingPolicy\":{\"automatic\":true,\"indexingMode\":\"Consistent\",\"includedPaths\":[{\"path\":\"/*\",\"indexes\":[{\"dataType\":\"Number\",\"precision\":-1,\"kind\":\"Range\"},{\"dataType\":\"String\",\"precision\":-1,\"kind\":\"Range\"}]}],\"excludedPaths\":[{\"path\":\"/\\\"_etag\\\"/?\"}],\"compositeIndexes\":[],\"spatialIndexes\":[],\"vectorIndexes\":[]},\"id\":\"MigrationTest\",\"partitionKey\":{\"paths\":[\"/id\"],\"kind\":\"Hash\"}}"; + string containerJsonString = "{\"indexingPolicy\":{\"automatic\":true,\"indexingMode\":\"Consistent\",\"includedPaths\":[{\"path\":\"/*\",\"indexes\":[{\"dataType\":\"Number\",\"precision\":-1,\"kind\":\"Range\"},{\"dataType\":\"String\",\"precision\":-1,\"kind\":\"Range\"}]}],\"excludedPaths\":[{\"path\":\"/\\\"_etag\\\"/?\"}],\"compositeIndexes\":[],\"spatialIndexes\":[],\"vectorIndexes\":[],\"fullTextIndexes\":[]},\"id\":\"MigrationTest\",\"partitionKey\":{\"paths\":[\"/id\"],\"kind\":\"Hash\"}}"; CosmosJsonDotNetSerializer serializerCore = new CosmosJsonDotNetSerializer(); ContainerProperties containerProperties = null; @@ -842,6 +861,7 @@ public void ContainerSettingsNullPartitionKeyTest() } [TestMethod] + [Ignore("This test will be enabled once the V2 DocumentCollection starts supporting the full text policy index.")] public async Task ContainerV2CompatTest() { string containerId = "SerializeContainerTest"; @@ -1113,6 +1133,54 @@ public void VectorEmbeddingPolicySerialization() Assert.IsTrue(embedding2.Equals(vectorEmbeddings.Value()[1].ToObject())); } + [TestMethod] + public void FullTextPolicySerialization() + { + ContainerProperties containerSettings = new ContainerProperties("TestContainer", "/pk"); + string serialization = JsonConvert.SerializeObject(containerSettings); + Assert.IsFalse(serialization.Contains("fullTextPolicy"), "Full Text Policy should not be included by default"); + + string defaultLanguage = "en-US", path1 = "/fts1", path2 = "/fts2", path3 = "/fts3"; + + FullTextPath fullTextPath1 = new Cosmos.FullTextPath() + { + Path = path1, + Language = "en-US", + }; + + FullTextPath fullTextPath2 = new Cosmos.FullTextPath() + { + Path = path2, + Language = "en-US", + }; + + FullTextPath fullTextPath3 = new Cosmos.FullTextPath() + { + Path = path3, + Language = "en-US", + }; + + Collection fullTextPaths = new Collection() + { + fullTextPath1, + fullTextPath2, + fullTextPath3, + }; + + containerSettings.FullTextPolicy = new Cosmos.FullTextPolicy(defaultLanguage, fullTextPaths); + + string serializationWithValues = JsonConvert.SerializeObject(containerSettings); + Assert.IsTrue(serializationWithValues.Contains("fullTextPolicy"), "Full Text Policy should be included."); + + JObject parsed = JObject.Parse(serializationWithValues); + JToken fullTextPathsDeSerialized = parsed["fullTextPolicy"]["fullTextPaths"]; + JToken fullTextLanguageDeSerialized = parsed["fullTextPolicy"]["defaultLanguage"]; + Assert.AreEqual(JTokenType.Array, fullTextPathsDeSerialized.Type, "Full Text Policy serialized paths should be an array."); + Assert.AreEqual(JTokenType.String, fullTextLanguageDeSerialized.Type, "Full Text Policy serialized language should be a string."); + Assert.IsTrue(fullTextPath1.Equals(fullTextPathsDeSerialized.Value()[0].ToObject())); + Assert.IsTrue(fullTextPath2.Equals(fullTextPathsDeSerialized.Value()[1].ToObject())); + } + private static T CosmosDeserialize(string payload) { using (MemoryStream ms = new MemoryStream()) From 20a47f1428f0176340b7edd35b54d391361287c7 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 13:48:39 -0700 Subject: [PATCH 03/10] Code changes make the full text search internal only for now. --- .../src/Fluent/Settings/ContainerBuilder.cs | 15 +++++---------- .../Fluent/Settings/FullTextIndexDefinition.cs | 7 +------ .../Fluent/Settings/FullTextPolicyDefinition.cs | 9 ++------- .../Fluent/Settings/IndexingPolicyDefinition.cs | 11 +++-------- .../src/Resource/Settings/ContainerProperties.cs | 9 ++------- .../src/Resource/Settings/FullTextIndexPath.cs | 7 +------ .../src/Resource/Settings/FullTextPath.cs | 9 ++------- .../src/Resource/Settings/FullTextPolicy.cs | 7 +------ .../src/Resource/Settings/IndexingPolicy.cs | 8 +------- 9 files changed, 18 insertions(+), 64 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs index 01bcb7e021..9af29a9795 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs @@ -138,17 +138,12 @@ VectorEmbeddingPolicyDefinition WithVectorEmbeddingPolicy( } /// - /// Defined the vector embedding policy for this Azure Cosmos container + /// Defined the full text policy for this Azure Cosmos container /// - /// blablan. - /// List of vector embeddings to include in the policy definition. - /// An instance of . -#if PREVIEW - public -#else - internal -#endif - FullTextPolicyDefinition WithFullTextPolicy( + /// A string indicating the default language for the inexing policy. + /// List of full text paths to include in the policy definition. + /// An instance of . + internal FullTextPolicyDefinition WithFullTextPolicy( string defaultLanguage, Collection fullTextPaths) { diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs index d84244011b..a5c1e3f312 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs @@ -10,12 +10,7 @@ namespace Microsoft.Azure.Cosmos.Fluent /// Full Text index fluent definition. /// /// -#if PREVIEW - public -#else - internal -#endif - class FullTextIndexDefinition + internal class FullTextIndexDefinition { private readonly FullTextIndexPath fullTextIndexPath = new (); private readonly T parent; diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs index aa04158798..6f16530c28 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs @@ -10,12 +10,7 @@ namespace Microsoft.Azure.Cosmos.Fluent /// /// fluent definition. /// -#if PREVIEW - public -#else - internal -#endif - class FullTextPolicyDefinition + internal class FullTextPolicyDefinition { private readonly ContainerBuilder parent; private readonly Action attachCallback; @@ -26,7 +21,7 @@ class FullTextPolicyDefinition /// Initializes a new instance of the class. /// /// The original instance of . - /// blabla + /// A string indicating the default language for the inexing policy definition. /// List of fullTextPaths to include in the policy definition. /// A callback delegate to be used at a later point of time. public FullTextPolicyDefinition( diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs index b87e4d3cd3..0f927a48f2 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs @@ -130,15 +130,10 @@ VectorIndexDefinition> WithVectorIndex() } /// - /// Defines a in the current 's definition. + /// Defines a in the current 's definition. /// - /// An instance of . -#if PREVIEW - public -#else - internal -#endif - FullTextIndexDefinition> WithFullTextIndex() + /// An instance of . + internal FullTextIndexDefinition> WithFullTextIndex() { return new FullTextIndexDefinition>( this, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs index f8af8b5b7d..61d9f5d29e 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs @@ -364,7 +364,7 @@ Collection ComputedProperties } /// - /// Gets or sets the full text policy containing paths for full text paths along with path-specific settings for the item + /// Gets or sets the full text policy containing paths for full text search along with path-specific settings for the item /// used in performing full text search on the items in a collection in the Azure CosmosDB database service. /// /// @@ -377,12 +377,7 @@ Collection ComputedProperties /// /// [JsonIgnore] -#if PREVIEW - public -#else - internal -#endif - FullTextPolicy FullTextPolicy + internal FullTextPolicy FullTextPolicy { get => this.fullTextPolicyInternal; diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs index f79855c2bf..e7056ed813 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs @@ -38,12 +38,7 @@ namespace Microsoft.Azure.Cosmos /// } /// ]]> /// -#if PREVIEW - public -#else - internal -#endif - sealed class FullTextIndexPath + internal sealed class FullTextIndexPath { /// /// Gets or sets the full path in a document used for full text indexing. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs index 09cd6c8de1..41003108bb 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs @@ -11,7 +11,7 @@ namespace Microsoft.Azure.Cosmos using Newtonsoft.Json.Linq; /// - /// DOM for a full text index policy. A full text policy is defined at the collection level. + /// DOM for a full text path. A full text path is defined at the collection level. /// /// /// /// -#if PREVIEW - public -#else - internal -#endif - sealed class FullTextPath : IEquatable + internal sealed class FullTextPath : IEquatable { /// /// Gets or sets a string containing the path of the full text index. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs index bea5efd551..cc80a8a534 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs @@ -12,12 +12,7 @@ namespace Microsoft.Azure.Cosmos /// Represents the full text policy configuration for specifying the full text paths on documents in the collection in the Azure Cosmos DB service. /// /// -#if PREVIEW - public -#else - internal -#endif - sealed class FullTextPolicy + internal sealed class FullTextPolicy { /// /// Initializes a new instance of the class. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs index d06a5acf99..964424266c 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs @@ -166,13 +166,7 @@ public IndexingPolicy() /// ]]> /// [JsonProperty(PropertyName = "fullTextIndexes", NullValueHandling = NullValueHandling.Ignore)] -#if PREVIEW - - public -#else - internal -#endif - Collection FullTextIndexes{ get; set; } = new Collection(); + internal Collection FullTextIndexes{ get; set; } = new Collection(); /// /// This contains additional values for scenarios where the SDK is not aware of new fields. From b48cc483fec75a0aca8dfd135790e6aea512ae77 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 14:19:10 -0700 Subject: [PATCH 04/10] Ignoring the FTS emulator tests. --- .../Fluent/ContainerSettingsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs index 7f654b9dd5..4728b0b355 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs @@ -683,7 +683,7 @@ await this.database.DefineContainer(containerName, partitionKeyPath) } [TestMethod] - //[Ignore("This test will be enabled once the full text search changes are made available into the public emulator.")] + [Ignore("This test will be enabled once the full text search changes are made available into the public emulator.")] public async Task TestFullTExtSearchPolicy() { string fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; From e7be9bf8d3831325322692c3acdd06acea85acd0 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 17:54:15 -0700 Subject: [PATCH 05/10] Code changes to address review comments. Made the FTS public for preview. --- .../src/Fluent/Settings/ContainerBuilder.cs | 13 +- .../Settings/FullTextIndexDefinition.cs | 9 +- .../Settings/FullTextPolicyDefinition.cs | 7 +- .../Settings/IndexingPolicyDefinition.cs | 7 +- .../Resource/Settings/ContainerProperties.cs | 11 +- .../Resource/Settings/FullTextIndexPath.cs | 7 +- .../src/Resource/Settings/FullTextPath.cs | 7 +- .../src/Resource/Settings/FullTextPolicy.cs | 11 +- .../src/Resource/Settings/IndexingPolicy.cs | 8 +- .../Fluent/ContainerSettingsTests.cs | 50 +++- .../Contracts/DotNetPreviewSDKAPI.json | 219 ++++++++++++++++++ .../CosmosContainerSettingsTests.cs | 43 ++++ 12 files changed, 373 insertions(+), 19 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs index 9af29a9795..c5f3e65536 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/ContainerBuilder.cs @@ -119,7 +119,7 @@ public ClientEncryptionPolicyDefinition WithClientEncryptionPolicy(int policyFor } /// - /// Defined the vector embedding policy for this Azure Cosmos container + /// Defines the vector embedding policy for this Azure Cosmos container /// /// List of vector embeddings to include in the policy definition. /// An instance of . @@ -138,12 +138,17 @@ VectorEmbeddingPolicyDefinition WithVectorEmbeddingPolicy( } /// - /// Defined the full text policy for this Azure Cosmos container + /// Defines the full text policy for this Azure Cosmos container /// - /// A string indicating the default language for the inexing policy. + /// A string indicating the default language. /// List of full text paths to include in the policy definition. /// An instance of . - internal FullTextPolicyDefinition WithFullTextPolicy( +#if PREVIEW + public +#else + internal +#endif + FullTextPolicyDefinition WithFullTextPolicy( string defaultLanguage, Collection fullTextPaths) { diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs index a5c1e3f312..241bbb3cc3 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextIndexDefinition.cs @@ -7,10 +7,15 @@ namespace Microsoft.Azure.Cosmos.Fluent using System; /// - /// Full Text index fluent definition. + /// Full text index fluent definition. /// /// - internal class FullTextIndexDefinition +#if PREVIEW + public +#else + internal +#endif + class FullTextIndexDefinition { private readonly FullTextIndexPath fullTextIndexPath = new (); private readonly T parent; diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs index 6f16530c28..9f48ca57a2 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs @@ -10,7 +10,12 @@ namespace Microsoft.Azure.Cosmos.Fluent /// /// fluent definition. /// - internal class FullTextPolicyDefinition +#if PREVIEW + public +#else + internal +#endif + class FullTextPolicyDefinition { private readonly ContainerBuilder parent; private readonly Action attachCallback; diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs index 0f927a48f2..bb109782ab 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/IndexingPolicyDefinition.cs @@ -133,7 +133,12 @@ VectorIndexDefinition> WithVectorIndex() /// Defines a in the current 's definition. /// /// An instance of . - internal FullTextIndexDefinition> WithFullTextIndex() +#if PREVIEW + public +#else + internal +#endif + FullTextIndexDefinition> WithFullTextIndex() { return new FullTextIndexDefinition>( this, diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs index 61d9f5d29e..4ddbcefbe8 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs @@ -364,8 +364,7 @@ Collection ComputedProperties } /// - /// Gets or sets the full text policy containing paths for full text search along with path-specific settings for the item - /// used in performing full text search on the items in a collection in the Azure CosmosDB database service. + /// Gets or sets the full text search paths for items in the container. /// /// /// It is an optional property. @@ -377,10 +376,14 @@ Collection ComputedProperties /// /// [JsonIgnore] - internal FullTextPolicy FullTextPolicy +#if PREVIEW + public +#else + internal +#endif + FullTextPolicy FullTextPolicy { get => this.fullTextPolicyInternal; - set => this.fullTextPolicyInternal = value; } diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs index e7056ed813..f79855c2bf 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextIndexPath.cs @@ -38,7 +38,12 @@ namespace Microsoft.Azure.Cosmos /// } /// ]]> /// - internal sealed class FullTextIndexPath +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextIndexPath { /// /// Gets or sets the full path in a document used for full text indexing. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs index 41003108bb..d191b3072b 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPath.cs @@ -31,7 +31,12 @@ namespace Microsoft.Azure.Cosmos /// } /// ]]> /// - internal sealed class FullTextPath : IEquatable +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextPath : IEquatable { /// /// Gets or sets a string containing the path of the full text index. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs index cc80a8a534..c93e11ed9b 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs @@ -9,10 +9,15 @@ namespace Microsoft.Azure.Cosmos using Newtonsoft.Json.Linq; /// - /// Represents the full text policy configuration for specifying the full text paths on documents in the collection in the Azure Cosmos DB service. + /// Represents the full text policy configuration for specifying the full text paths on items in the container in the Azure Cosmos DB service. /// /// - internal sealed class FullTextPolicy +#if PREVIEW + public +#else + internal +#endif + sealed class FullTextPolicy { /// /// Initializes a new instance of the class. @@ -42,7 +47,7 @@ public FullTextPolicy( /// Gets a collection of that contains the full text paths of documents in collection in the Azure Cosmos DB service. /// [JsonProperty(PropertyName = "fullTextPaths", NullValueHandling = NullValueHandling.Ignore)] - public readonly Collection FullTextPaths; + public readonly Collection FullTextPaths = new Collection(); /// /// This contains additional values for scenarios where the SDK is not aware of new fields. diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs index 964424266c..d06a5acf99 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/IndexingPolicy.cs @@ -166,7 +166,13 @@ public IndexingPolicy() /// ]]> /// [JsonProperty(PropertyName = "fullTextIndexes", NullValueHandling = NullValueHandling.Ignore)] - internal Collection FullTextIndexes{ get; set; } = new Collection(); +#if PREVIEW + + public +#else + internal +#endif + Collection FullTextIndexes{ get; set; } = new Collection(); /// /// This contains additional values for scenarios where the SDK is not aware of new fields. diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs index 4728b0b355..7a48a29fa7 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs @@ -684,7 +684,7 @@ await this.database.DefineContainer(containerName, partitionKeyPath) [TestMethod] [Ignore("This test will be enabled once the full text search changes are made available into the public emulator.")] - public async Task TestFullTExtSearchPolicy() + public async Task TestFullTextSearchPolicy() { string fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; Database databaseForVectorEmbedding = await this.GetClient().CreateDatabaseAsync("fullTextSearchDB", @@ -757,6 +757,54 @@ await databaseForVectorEmbedding.DefineContainer(containerName, partitionKeyPath } } + [TestMethod] + [Ignore("This test will be enabled once the full text search changes are made available into the public emulator.")] + public async Task TestFullTextSearchPolicyWithDefaultLanguage() + { + string fullTextPath1 = "/fts1"; + Database databaseForVectorEmbedding = await this.GetClient().CreateDatabaseAsync("fullTextSearchDB", + cancellationToken: this.cancellationToken); + + try + { + string containerName = "fullTextContainerTest"; + string partitionKeyPath = "/pk"; + + ContainerResponse containerResponse = + await databaseForVectorEmbedding.DefineContainer(containerName, partitionKeyPath) + .WithFullTextPolicy( + defaultLanguage: "en-US", + fullTextPaths: new Collection()) + .Attach() + .WithIndexingPolicy() + .WithFullTextIndex() + .Path(fullTextPath1) + .Attach() + .Attach() + .CreateAsync(); + + Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode); + Assert.AreEqual(containerName, containerResponse.Resource.Id); + Assert.AreEqual(partitionKeyPath, containerResponse.Resource.PartitionKey.Paths.First()); + ContainerProperties containerSettings = containerResponse.Resource; + + // Validate FullText Paths. + Assert.IsNotNull(containerSettings.FullTextPolicy); + Assert.IsNotNull(containerSettings.FullTextPolicy.FullTextPaths); + Assert.AreEqual(fullTextPaths.Count, containerSettings.FullTextPolicy.FullTextPaths.Count()); + Assert.IsTrue(fullTextPaths.OrderBy(x => x.Path).SequenceEqual(containerSettings.FullTextPolicy.FullTextPaths.OrderBy(x => x.Path))); + + // Validate Full Text Indexes. + Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes); + Assert.AreEqual(fullTextPaths.Count, containerSettings.IndexingPolicy.FullTextIndexes.Count()); + Assert.AreEqual(fullTextPath1, containerSettings.IndexingPolicy.FullTextIndexes[0].Path); + } + finally + { + await databaseForVectorEmbedding.DeleteAsync(); + } + } + [Ignore] [TestMethod] public async Task WithComputedProperties() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json index 6ca79014f5..852c2294ee 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json @@ -346,6 +346,18 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.ChangeFeedPolicy get_ChangeFeedPolicy();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.FullTextPolicy FullTextPolicy[Newtonsoft.Json.JsonIgnoreAttribute()]": { + "Type": "Property", + "Attributes": [ + "JsonIgnoreAttribute" + ], + "MethodInfo": "Microsoft.Azure.Cosmos.FullTextPolicy FullTextPolicy;CanRead:True;CanWrite:True;Microsoft.Azure.Cosmos.FullTextPolicy get_FullTextPolicy();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_FullTextPolicy(Microsoft.Azure.Cosmos.FullTextPolicy);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Microsoft.Azure.Cosmos.FullTextPolicy get_FullTextPolicy()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.FullTextPolicy get_FullTextPolicy();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.VectorEmbeddingPolicy get_VectorEmbeddingPolicy()": { "Type": "Method", "Attributes": [], @@ -380,6 +392,11 @@ "Attributes": [], "MethodInfo": "Void set_ComputedProperties(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.ComputedProperty]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Void set_FullTextPolicy(Microsoft.Azure.Cosmos.FullTextPolicy)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Void set_FullTextPolicy(Microsoft.Azure.Cosmos.FullTextPolicy);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Void set_VectorEmbeddingPolicy(Microsoft.Azure.Cosmos.VectorEmbeddingPolicy)": { "Type": "Method", "Attributes": [], @@ -587,6 +604,11 @@ "Attributes": [], "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.ChangeFeedPolicyDefinition WithChangeFeedPolicy(System.TimeSpan);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Microsoft.Azure.Cosmos.Fluent.FullTextPolicyDefinition WithFullTextPolicy(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.FullTextPolicyDefinition WithFullTextPolicy(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.Fluent.VectorEmbeddingPolicyDefinition WithVectorEmbeddingPolicy(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.Embedding])": { "Type": "Method", "Attributes": [], @@ -617,9 +639,51 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.Fluent.FullTextIndexDefinition`1;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:True;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.Fluent.FullTextIndexDefinition`1[T] Path(System.String)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.FullTextIndexDefinition`1[T] Path(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "T Attach()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "T Attach();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor(T, System.Action`1[Microsoft.Azure.Cosmos.FullTextIndexPath])": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(T, System.Action`1[Microsoft.Azure.Cosmos.FullTextIndexPath]), Void .ctor(T, System.Action`1[Microsoft.Azure.Cosmos.FullTextIndexPath])]" + } + }, + "NestedTypes": {} + }, + "Microsoft.Azure.Cosmos.Fluent.FullTextPolicyDefinition;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Microsoft.Azure.Cosmos.Fluent.ContainerBuilder Attach()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.ContainerBuilder Attach();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor(Microsoft.Azure.Cosmos.Fluent.ContainerBuilder, System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath], System.Action`1[Microsoft.Azure.Cosmos.FullTextPolicy])": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(Microsoft.Azure.Cosmos.Fluent.ContainerBuilder, System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath], System.Action`1[Microsoft.Azure.Cosmos.FullTextPolicy]), Void .ctor(Microsoft.Azure.Cosmos.Fluent.ContainerBuilder, System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath], System.Action`1[Microsoft.Azure.Cosmos.FullTextPolicy])]" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.Fluent.IndexingPolicyDefinition`1;System.Object;IsAbstract:False;IsSealed:False;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:True;IsSerializable:False": { "Subclasses": {}, "Members": { + "Microsoft.Azure.Cosmos.Fluent.FullTextIndexDefinition`1[Microsoft.Azure.Cosmos.Fluent.IndexingPolicyDefinition`1[T]] WithFullTextIndex()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Microsoft.Azure.Cosmos.Fluent.FullTextIndexDefinition`1[Microsoft.Azure.Cosmos.Fluent.IndexingPolicyDefinition`1[T]] WithFullTextIndex();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Microsoft.Azure.Cosmos.Fluent.VectorIndexDefinition`1[Microsoft.Azure.Cosmos.Fluent.IndexingPolicyDefinition`1[T]] WithVectorIndex()": { "Type": "Method", "Attributes": [], @@ -680,9 +744,157 @@ }, "NestedTypes": {} }, + "Microsoft.Azure.Cosmos.FullTextIndexPath;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "System.String get_Path()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.String get_Path();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String Path[Newtonsoft.Json.JsonPropertyAttribute(PropertyName = \"path\")]": { + "Type": "Property", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.String Path;CanRead:True;CanWrite:True;System.String get_Path();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_Path(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor()": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(), Void .ctor()]" + }, + "Void set_Path(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_Path(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, + "Microsoft.Azure.Cosmos.FullTextPath;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "Boolean Equals(Microsoft.Azure.Cosmos.FullTextPath)": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Boolean Equals(Microsoft.Azure.Cosmos.FullTextPath);IsAbstract:False;IsStatic:False;IsVirtual:True;IsGenericMethod:False;IsConstructor:False;IsFinal:True;" + }, + "System.String get_Language()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.String get_Language();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String get_Path()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.String get_Path();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String Language[Newtonsoft.Json.JsonPropertyAttribute(PropertyName = \"language\")]": { + "Type": "Property", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.String Language;CanRead:True;CanWrite:True;System.String get_Language();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_Language(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String Path[Newtonsoft.Json.JsonPropertyAttribute(PropertyName = \"path\")]": { + "Type": "Property", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.String Path;CanRead:True;CanWrite:True;System.String get_Path();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_Path(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor()": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(), Void .ctor()]" + }, + "Void set_Language(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_Language(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void set_Path(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_Path(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void ValidateFullTextPath()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Void ValidateFullTextPath();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, + "Microsoft.Azure.Cosmos.FullTextPolicy;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { + "Subclasses": {}, + "Members": { + "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths[Newtonsoft.Json.JsonPropertyAttribute(NullValueHandling = 1, PropertyName = \"fullTextPaths\")]": { + "Type": "Field", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths;IsInitOnly:True;IsStatic:False;" + }, + "System.String DefaultLanguage[Newtonsoft.Json.JsonPropertyAttribute(NullValueHandling = 1, PropertyName = \"defaultLanguage\")]": { + "Type": "Property", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.String DefaultLanguage;CanRead:True;CanWrite:True;System.String get_DefaultLanguage();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_DefaultLanguage(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.String get_DefaultLanguage()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.String get_DefaultLanguage();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])": { + "Type": "Constructor", + "Attributes": [], + "MethodInfo": "[Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath]), Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])]" + }, + "Void set_DefaultLanguage(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_DefaultLanguage(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + } + }, + "NestedTypes": {} + }, "Microsoft.Azure.Cosmos.IndexingPolicy;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { + "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath] FullTextIndexes[Newtonsoft.Json.JsonPropertyAttribute(NullValueHandling = 1, PropertyName = \"fullTextIndexes\")]": { + "Type": "Property", + "Attributes": [ + "JsonPropertyAttribute" + ], + "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath] FullTextIndexes;CanRead:True;CanWrite:True;System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath] get_FullTextIndexes();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_FullTextIndexes(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath] get_FullTextIndexes()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath] get_FullTextIndexes();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.VectorIndexPath] get_VectorIndexes()[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ @@ -697,6 +909,13 @@ ], "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.VectorIndexPath] VectorIndexes;CanRead:True;CanWrite:True;System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.VectorIndexPath] get_VectorIndexes();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_VectorIndexes(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.VectorIndexPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, + "Void set_FullTextIndexes(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath])[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { + "Type": "Method", + "Attributes": [ + "CompilerGeneratedAttribute" + ], + "MethodInfo": "Void set_FullTextIndexes(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextIndexPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, "Void set_VectorIndexes(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.VectorIndexPath])[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", "Attributes": [ diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs index d7e87168bc..2a85793a13 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs @@ -323,6 +323,9 @@ public void ValidateFullTextPathsAndIndexes() Cosmos.FullTextPolicy fullTextPolicy = containerSettings.FullTextPolicy; Assert.IsNotNull(fullTextPolicy.FullTextPaths); Assert.AreEqual(fullTextPaths.Count, fullTextPolicy.FullTextPaths.Count()); + Assert.AreEqual(fullTextPaths[0].Path, fullTextPolicy.FullTextPaths[0].Path); + Assert.AreEqual(fullTextPaths[0].Language, fullTextPolicy.FullTextPaths[0].Language); + CollectionAssert.AreEquivalent(fullTextPaths, fullTextPolicy.FullTextPaths.ToList()); Collection fullTextIndexes = containerSettings.IndexingPolicy.FullTextIndexes; @@ -331,6 +334,46 @@ public void ValidateFullTextPathsAndIndexes() Assert.AreEqual("/fts3", fullTextIndexes[2].Path); } + [TestMethod] + public void ValidateFullTextPathsAndIndexesWithDefaultLanguage() + { + string defaultLanguage = "en-US", fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; + ContainerProperties containerSettings = new ContainerProperties(id: "TestContainer", partitionKeyPath: "/partitionKey") + { + FullTextPolicy = new(defaultLanguage, fullTextPaths: new Collection()), + IndexingPolicy = new Cosmos.IndexingPolicy() + { + FullTextIndexes = new() + { + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath1, + }, + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath2, + }, + new Cosmos.FullTextIndexPath() + { + Path = fullTextPath3, + } + }, + }, + }; + + Assert.IsNotNull(containerSettings.IndexingPolicy); + Assert.IsNotNull(containerSettings.FullTextPolicy); + Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes); + + Cosmos.FullTextPolicy fullTextPolicy = containerSettings.FullTextPolicy; + Assert.AreEqual(0, fullTextPolicy.FullTextPaths.Count); + + Collection fullTextIndexes = containerSettings.IndexingPolicy.FullTextIndexes; + Assert.AreEqual("/fts1", fullTextIndexes[0].Path); + Assert.AreEqual("/fts2", fullTextIndexes[1].Path); + Assert.AreEqual("/fts3", fullTextIndexes[2].Path); + } + private static string SerializeDocumentCollection(DocumentCollection collection) { using (MemoryStream ms = new MemoryStream()) From f5f5fa82305cf316f7bdb8320a813d473a9f7c8e Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 18:03:01 -0700 Subject: [PATCH 06/10] Code changes to update verbaige. --- .../src/Resource/Settings/ContainerProperties.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs index 4ddbcefbe8..0fbdd3d587 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/ContainerProperties.cs @@ -372,7 +372,7 @@ Collection ComputedProperties /// /// /// - /// The will be applied to all the items in the container as the default policy. + /// The will be applied to all the items in the container. /// /// [JsonIgnore] From 5377b39312c5ab03faa2f0c3a9eb11ce11553aea Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 21:16:20 -0700 Subject: [PATCH 07/10] Code changes to fix test failures. --- .../CosmosContainerSettingsTests.cs | 1 + .../Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs index 2a85793a13..d7f736f8af 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs @@ -102,6 +102,7 @@ public void DefaultSameAsDocumentCollection() } [TestMethod] + [Ignore("This test will be enabled once the V2 DocumentCollection starts supporting the full text indexing policy.")] public void DefaultIndexingPolicySameAsDocumentCollection() { ContainerProperties containerSettings = new ContainerProperties("TestContainer", "/partitionKey") diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs index 4e806c2205..f191f93bbd 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs @@ -769,7 +769,8 @@ public void ContainerSettingsDefaults() "ChangeFeedPolicy", "ClientEncryptionPolicy", "PartitionKeyPaths", - "VectorEmbeddingPolicy"); + "VectorEmbeddingPolicy", + "FullTextPolicy"); #else SettingsContractTests.TypeAccessorGuard(typeof(ContainerProperties), "Id", @@ -784,7 +785,8 @@ public void ContainerSettingsDefaults() "ConflictResolutionPolicy", "ClientEncryptionPolicy", "PartitionKeyPaths", - "VectorEmbeddingPolicy"); + "VectorEmbeddingPolicy," + + "FullTextPolicy"); #endif // Two equivalent definitions From 7e84283292fb785b9f474b793c39564f256a4a08 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Mon, 21 Oct 2024 21:33:24 -0700 Subject: [PATCH 08/10] Code changes to fix build failure. --- .../Fluent/ContainerSettingsTests.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs index 7a48a29fa7..ccae6e036c 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.EmulatorTests/Fluent/ContainerSettingsTests.cs @@ -791,12 +791,11 @@ await databaseForVectorEmbedding.DefineContainer(containerName, partitionKeyPath // Validate FullText Paths. Assert.IsNotNull(containerSettings.FullTextPolicy); Assert.IsNotNull(containerSettings.FullTextPolicy.FullTextPaths); - Assert.AreEqual(fullTextPaths.Count, containerSettings.FullTextPolicy.FullTextPaths.Count()); - Assert.IsTrue(fullTextPaths.OrderBy(x => x.Path).SequenceEqual(containerSettings.FullTextPolicy.FullTextPaths.OrderBy(x => x.Path))); + Assert.AreEqual(0, containerSettings.FullTextPolicy.FullTextPaths.Count()); // Validate Full Text Indexes. Assert.IsNotNull(containerSettings.IndexingPolicy.FullTextIndexes); - Assert.AreEqual(fullTextPaths.Count, containerSettings.IndexingPolicy.FullTextIndexes.Count()); + Assert.AreEqual(1, containerSettings.IndexingPolicy.FullTextIndexes.Count()); Assert.AreEqual(fullTextPath1, containerSettings.IndexingPolicy.FullTextIndexes[0].Path); } finally From 52a21b91d14d67eb8bf13d9fb0b9680e7d2b1294 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Tue, 22 Oct 2024 16:16:40 -0700 Subject: [PATCH 09/10] Code changes to address review comments. --- .../Settings/FullTextPolicyDefinition.cs | 8 +++-- .../src/Resource/Settings/FullTextPolicy.cs | 34 ++++++++----------- .../CosmosContainerSettingsTests.cs | 12 +++++-- .../SettingsContractTests.cs | 6 +++- 4 files changed, 34 insertions(+), 26 deletions(-) diff --git a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs index 9f48ca57a2..1c8d69ecc7 100644 --- a/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs +++ b/Microsoft.Azure.Cosmos/src/Fluent/Settings/FullTextPolicyDefinition.cs @@ -47,9 +47,11 @@ public FullTextPolicyDefinition( /// An instance of the parent. public ContainerBuilder Attach() { - FullTextPolicy fullTextPolicy = new ( - this.defaultLanguage, - this.fullTextPaths); + FullTextPolicy fullTextPolicy = new () + { + DefaultLanguage = this.defaultLanguage, + FullTextPaths = this.fullTextPaths + }; this.attachCallback(fullTextPolicy); return this.parent; diff --git a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs index c93e11ed9b..147dc7f752 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/Settings/FullTextPolicy.cs @@ -19,23 +19,8 @@ namespace Microsoft.Azure.Cosmos #endif sealed class FullTextPolicy { - /// - /// Initializes a new instance of the class. - /// - /// String of the default language of the container. - /// List of full text paths to include in the policy definition. - public FullTextPolicy( - string defaultLanguage, - Collection fullTextPaths) - { - if (fullTextPaths != null) - { - FullTextPolicy.ValidateFullTextPaths(fullTextPaths); - } - - this.DefaultLanguage = defaultLanguage; - this.FullTextPaths = fullTextPaths; - } + [JsonProperty(PropertyName = "fullTextPaths", NullValueHandling = NullValueHandling.Ignore)] + private Collection fullTextPathsInternal; /// /// Gets or sets a string containing the default language of the container. @@ -44,10 +29,19 @@ public FullTextPolicy( public string DefaultLanguage { get; set; } /// - /// Gets a collection of that contains the full text paths of documents in collection in the Azure Cosmos DB service. + /// Gets or sets a collection of that contains the full text paths of documents in + /// a collection in the Azure Cosmos DB service. /// - [JsonProperty(PropertyName = "fullTextPaths", NullValueHandling = NullValueHandling.Ignore)] - public readonly Collection FullTextPaths = new Collection(); + [JsonIgnore] + public Collection FullTextPaths + { + get => this.fullTextPathsInternal; + set + { + FullTextPolicy.ValidateFullTextPaths(value); + this.fullTextPathsInternal = value; + } + } /// /// This contains additional values for scenarios where the SDK is not aware of new fields. diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs index d7f736f8af..0ba0f72ea3 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosContainerSettingsTests.cs @@ -296,7 +296,11 @@ public void ValidateFullTextPathsAndIndexes() ContainerProperties containerSettings = new ContainerProperties(id: "TestContainer", partitionKeyPath: "/partitionKey") { - FullTextPolicy = new(defaultLanguage, fullTextPaths), + FullTextPolicy = new() + { + DefaultLanguage = defaultLanguage, + FullTextPaths = fullTextPaths + }, IndexingPolicy = new Cosmos.IndexingPolicy() { FullTextIndexes = new() @@ -341,7 +345,11 @@ public void ValidateFullTextPathsAndIndexesWithDefaultLanguage() string defaultLanguage = "en-US", fullTextPath1 = "/fts1", fullTextPath2 = "/fts2", fullTextPath3 = "/fts3"; ContainerProperties containerSettings = new ContainerProperties(id: "TestContainer", partitionKeyPath: "/partitionKey") { - FullTextPolicy = new(defaultLanguage, fullTextPaths: new Collection()), + FullTextPolicy = new() + { + DefaultLanguage = defaultLanguage, + FullTextPaths = new Collection() + }, IndexingPolicy = new Cosmos.IndexingPolicy() { FullTextIndexes = new() diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs index f191f93bbd..48b2a53692 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/SettingsContractTests.cs @@ -1169,7 +1169,11 @@ public void FullTextPolicySerialization() fullTextPath3, }; - containerSettings.FullTextPolicy = new Cosmos.FullTextPolicy(defaultLanguage, fullTextPaths); + containerSettings.FullTextPolicy = new Cosmos.FullTextPolicy() + { + DefaultLanguage = defaultLanguage, + FullTextPaths = fullTextPaths, + }; string serializationWithValues = JsonConvert.SerializeObject(containerSettings); Assert.IsTrue(serializationWithValues.Contains("fullTextPolicy"), "Full Text Policy should be included."); From 467de772a29d4408073fc6c5303df61d929eebc0 Mon Sep 17 00:00:00 2001 From: Debdatta Kunda Date: Tue, 22 Oct 2024 16:54:11 -0700 Subject: [PATCH 10/10] Code changes to update preview contract --- .../Contracts/DotNetPreviewSDKAPI.json | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json index 852c2294ee..e0a6cb8a99 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/Contracts/DotNetPreviewSDKAPI.json @@ -842,12 +842,17 @@ "Microsoft.Azure.Cosmos.FullTextPolicy;System.Object;IsAbstract:False;IsSealed:True;IsInterface:False;IsEnum:False;IsClass:True;IsValueType:False;IsNested:False;IsGenericType:False;IsSerializable:False": { "Subclasses": {}, "Members": { - "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths[Newtonsoft.Json.JsonPropertyAttribute(NullValueHandling = 1, PropertyName = \"fullTextPaths\")]": { - "Type": "Field", + "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths[Newtonsoft.Json.JsonIgnoreAttribute()]": { + "Type": "Property", "Attributes": [ - "JsonPropertyAttribute" + "JsonIgnoreAttribute" ], - "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths;IsInitOnly:True;IsStatic:False;" + "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] FullTextPaths;CanRead:True;CanWrite:True;System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] get_FullTextPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;Void set_FullTextPaths(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] get_FullTextPaths()": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath] get_FullTextPaths();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, "System.String DefaultLanguage[Newtonsoft.Json.JsonPropertyAttribute(NullValueHandling = 1, PropertyName = \"defaultLanguage\")]": { "Type": "Property", @@ -863,10 +868,10 @@ ], "MethodInfo": "System.String get_DefaultLanguage();IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" }, - "Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])": { + "Void .ctor()": { "Type": "Constructor", "Attributes": [], - "MethodInfo": "[Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath]), Void .ctor(System.String, System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])]" + "MethodInfo": "[Void .ctor(), Void .ctor()]" }, "Void set_DefaultLanguage(System.String)[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]": { "Type": "Method", @@ -874,6 +879,11 @@ "CompilerGeneratedAttribute" ], "MethodInfo": "Void set_DefaultLanguage(System.String);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" + }, + "Void set_FullTextPaths(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath])": { + "Type": "Method", + "Attributes": [], + "MethodInfo": "Void set_FullTextPaths(System.Collections.ObjectModel.Collection`1[Microsoft.Azure.Cosmos.FullTextPath]);IsAbstract:False;IsStatic:False;IsVirtual:False;IsGenericMethod:False;IsConstructor:False;IsFinal:False;" } }, "NestedTypes": {}