@@ -18,85 +18,110 @@ namespace Microsoft.Azure.Cosmos.EmulatorTests.Query
1818 [ TestCategory ( "Query" ) ]
1919 public sealed class HybridSearchQueryTests : QueryTestsBase
2020 {
21- private const string CollectionDataPath = "D: \\ cosmosdb \\ Product \\ Backend \\ native \\ Test \\ resources \\ TestInput \\ FullText \\ text-3properties-1536dimensions-100documents.json" ;
21+ private const string CollectionDataPath = "Documents \\ text-3properties-1536dimensions-100documents.json" ;
2222
2323 private static readonly IndexingPolicy CompositeIndexPolicy = CreateIndexingPolicy ( ) ;
2424
2525 [ TestMethod ]
26- public async Task AllTests ( )
26+ public async Task SanityTests ( )
2727 {
28- Trace . WriteLine ( "Started HybridSearchQueryTests.AllTests ..." ) ;
28+ Trace . WriteLine ( "Started HybridSearchQueryTests.SanityTests ..." ) ;
2929 Trace . AutoFlush = true ;
3030
31- IReadOnlyList < string > documents = await LoadDocuments ( ) ;
31+ CosmosArray documentsArray = await LoadDocuments ( ) ;
32+ IEnumerable < string > documents = documentsArray . Select ( document => document . ToString ( ) ) ;
3233
3334 await this . CreateIngestQueryDeleteAsync (
3435 connectionModes : ConnectionModes . Direct , // | ConnectionModes.Gateway,
3536 collectionTypes : CollectionTypes . MultiPartition , // | CollectionTypes.SinglePartition,
3637 documents : documents ,
37- query : RunTests ,
38+ query : RunSanityTests ,
3839 indexingPolicy : CompositeIndexPolicy ) ;
3940 }
4041
41- private static async Task RunTests ( Container container , IReadOnlyList < CosmosObject > _ )
42+ private static async Task RunSanityTests ( Container container , IReadOnlyList < CosmosObject > _ )
4243 {
43- List < string > queryText = new List < string >
44+ List < SanityTest > testCases = new List < SanityTest >
4445 {
45- //@"
46- //SELECT c.title AS Title, c.text AS Text
47- //FROM c
48- //WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John')
49- //ORDER BY RANK FullTextScore(c.title, ['John'])",
50- @"
51- SELECT c.title AS Title, c.text AS Text
52- FROM c
53- WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John') OR FullTextContains(c.text, 'United States')
54- ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))" ,
46+ MakeSanityTest ( @"
47+ SELECT c.index AS Index, c.title AS Title, c.text AS Text
48+ FROM c
49+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John')
50+ ORDER BY RANK FullTextScore(c.title, ['John'])" ,
51+ new List < int > { 2 , 57 , 85 } ) ,
52+ MakeSanityTest ( @"
53+ SELECT TOP 10 c.index AS Index, c.title AS Title, c.text AS Text
54+ FROM c
55+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John')
56+ ORDER BY RANK FullTextScore(c.title, ['John'])" ,
57+ new List < int > { 2 , 57 , 85 } ) ,
58+ MakeSanityTest ( @"
59+ SELECT c.index AS Index, c.title AS Title, c.text AS Text
60+ FROM c
61+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John')
62+ ORDER BY RANK FullTextScore(c.title, ['John'])
63+ OFFSET 1 LIMIT 5" ,
64+ new List < int > { 57 , 85 } ) ,
65+ MakeSanityTest ( @"
66+ SELECT c.index AS Index, c.title AS Title, c.text AS Text
67+ FROM c
68+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John') OR FullTextContains(c.text, 'United States')
69+ ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))" ,
70+ new List < int > { 61 , 51 , 49 , 54 , 75 , 24 , 77 , 76 , 80 , 25 , 22 , 2 , 66 , 57 , 85 } ) ,
71+ MakeSanityTest ( @"
72+ SELECT TOP 10 c.index AS Index, c.title AS Title, c.text AS Text
73+ FROM c
74+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John') OR FullTextContains(c.text, 'United States')
75+ ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))" ,
76+ new List < int > { 61 , 51 , 49 , 54 , 75 , 24 , 77 , 76 , 80 , 25 } ) ,
77+ MakeSanityTest ( @"
78+ SELECT c.index AS Index, c.title AS Title, c.text AS Text
79+ FROM c
80+ WHERE FullTextContains(c.title, 'John') OR FullTextContains(c.text, 'John') OR FullTextContains(c.text, 'United States')
81+ ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))
82+ OFFSET 5 LIMIT 10" ,
83+ new List < int > { 24 , 77 , 76 , 80 , 25 , 22 , 2 , 66 , 57 , 85 } ) ,
84+ MakeSanityTest ( @"
85+ SELECT TOP 10 c.index AS Index, c.title AS Title, c.text AS Text
86+ FROM c
87+ ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))" ,
88+ new List < int > { 61 , 51 , 49 , 54 , 75 , 24 , 77 , 76 , 80 , 25 } ) ,
89+ MakeSanityTest ( @"
90+ SELECT c.index AS Index, c.title AS Title, c.text AS Text
91+ FROM c
92+ ORDER BY RANK RRF(FullTextScore(c.title, ['John']), FullTextScore(c.text, ['United States']))
93+ OFFSET 0 LIMIT 13" ,
94+ new List < int > { 61 , 51 , 49 , 54 , 75 , 24 , 77 , 76 , 80 , 25 , 22 , 2 , 66 } ) ,
5595 } ;
5696
57- foreach ( string query in queryText )
97+ foreach ( SanityTest testCase in testCases )
5898 {
59- await RunTestAsync ( container , query ) ;
60- }
61- }
99+ List < TextDocument > result = await RunQueryCombinationsAsync < TextDocument > (
100+ container ,
101+ testCase . Query ,
102+ queryRequestOptions : null ,
103+ queryDrainingMode : QueryDrainingMode . HoldState ) ;
62104
63- private static async Task RunTestAsync ( Container container , string queryText )
64- {
65- List < TextDocument > result = await RunQueryCombinationsAsync < TextDocument > (
66- container ,
67- queryText ,
68- queryRequestOptions : null ,
69- queryDrainingMode : QueryDrainingMode . HoldState ) ;
70- Assert . IsTrue ( result . Count > 0 ) ;
105+ IEnumerable < int > actual = result . Select ( document => document . Index ) ;
106+ if ( ! testCase . ExpectedIndices . SequenceEqual ( actual ) )
107+ {
108+ Trace . WriteLine ( $ "Query: { testCase . Query } ") ;
109+ Trace . WriteLine ( $ "Expected: { string . Join ( ", " , testCase . ExpectedIndices ) } ") ;
110+ Trace . WriteLine ( $ "Actual: { string . Join ( ", " , actual ) } ") ;
111+ Assert . Fail ( "The query results did not match the expected results." ) ;
112+ }
113+ }
71114 }
72115
73- private static async Task < IReadOnlyList < string > > LoadDocuments ( )
116+ private static async Task < CosmosArray > LoadDocuments ( )
74117 {
75118 // read the json file
76119 string json = await File . ReadAllTextAsync ( CollectionDataPath ) ;
77120 byte [ ] jsonBuffer = Encoding . UTF8 . GetBytes ( json ) ;
78121 ReadOnlyMemory < byte > readOnlyMemory = new ReadOnlyMemory < byte > ( jsonBuffer ) ;
79122 CosmosObject rootObject = CosmosObject . CreateFromBuffer ( readOnlyMemory ) ;
80- if ( ! rootObject . TryGetValue ( FieldNames . Items , out CosmosArray items ) )
81- {
82- throw new InvalidOperationException ( "Failed to find items in the json file." ) ;
83- }
84-
85- int index = 0 ;
86- List < string > documents = new List < string > ( ) ;
87- foreach ( CosmosElement item in items )
88- {
89- CosmosObject itemObject = item as CosmosObject ;
90- Dictionary < string , CosmosElement > itemDictionary = new ( itemObject )
91- {
92- { "index" , CosmosNumber . Parse ( index . ToString ( ) ) }
93- } ;
94-
95- CosmosObject rewrittenItem = CosmosObject . Create ( itemDictionary ) ;
96- documents . Add ( rewrittenItem . ToString ( ) ) ;
97- }
98-
99- return documents ;
123+ Assert . IsTrue ( rootObject . TryGetValue ( FieldNames . Items , out CosmosArray items ) , "Failed to find items in the json file." ) ;
124+ return items ;
100125 }
101126
102127 private static IndexingPolicy CreateIndexingPolicy ( )
@@ -113,8 +138,26 @@ private static IndexingPolicy CreateIndexingPolicy()
113138 return policy ;
114139 }
115140
141+ private static SanityTest MakeSanityTest ( string query , IReadOnlyList < int > expectedIndices )
142+ {
143+ return new SanityTest
144+ {
145+ Query = query ,
146+ ExpectedIndices = expectedIndices ,
147+ } ;
148+ }
149+
150+ private sealed class SanityTest
151+ {
152+ public string Query { get ; init ; }
153+
154+ public IReadOnlyList < int > ExpectedIndices { get ; init ; }
155+ }
156+
116157 private sealed class TextDocument
117158 {
159+ public int Index { get ; set ; }
160+
118161 public string Title { get ; set ; }
119162
120163 public string Text { get ; set ; }
@@ -123,6 +166,8 @@ private sealed class TextDocument
123166 private static class FieldNames
124167 {
125168 public const string Items = "items" ;
169+ public const string Title = "title" ;
170+ public const string Text = "text" ;
126171 }
127172 }
128- }
173+ }
0 commit comments