Skip to content

Commit f4f34fe

Browse files
TomKlotzProAnt-hemsbellone
authored
feat: support facet ordering (#780)
Co-authored-by: Antoine Hémery <[email protected]> Co-authored-by: Sylvain Bellone <[email protected]>
1 parent a6df558 commit f4f34fe

File tree

9 files changed

+254
-3
lines changed

9 files changed

+254
-3
lines changed

src/Algolia.Search.Test/Serializer/SerializerTest.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,71 @@ public void TestRecommendResponse()
907907
Assert.That(recommendedProducts.ElementAt(0).Url, Is.EqualTo("men/t-shirts/d05927-8161-111"));
908908
Assert.That(recommendedProducts.ElementAt(0).ImageLink, Is.EqualTo("https://example.org/image/D05927-8161-111-F01.jpg"));
909909
}
910+
911+
[Test]
912+
[Parallelizable]
913+
public void TestFacetOrdering()
914+
{
915+
// Test serialization
916+
var settings = new IndexSettings
917+
{
918+
RenderingContent = new RenderingContent
919+
{
920+
FacetOrdering = new FacetOrdering
921+
{
922+
Facets = new FacetsOrder
923+
{
924+
Order = new List<string> { "size", "brand" }
925+
},
926+
Values = new Dictionary<string, FacetValuesOrder>
927+
{
928+
{ "brand", new FacetValuesOrder { Order = new List<string> { "uniqlo" } } },
929+
{ "size", new FacetValuesOrder
930+
{
931+
Order = new List<string> { "S", "M", "L" },
932+
SortRemainingBy = "hidden"
933+
}
934+
}
935+
}
936+
}
937+
}
938+
};
939+
940+
string json = JsonConvert.SerializeObject(settings, JsonConfig.AlgoliaJsonSerializerSettings);
941+
Assert.AreEqual("{\"renderingContent\":{\"facetOrdering\":{\"facets\":{\"order\":[\"size\",\"brand\"]},\"values\":{\"brand\":{\"order\":[\"uniqlo\"]},\"size\":{\"order\":[\"S\",\"M\",\"L\"],\"sortRemainingBy\":\"hidden\"}}}}}", json);
942+
943+
// Test deserialization
944+
var payload = @"{
945+
""renderingContent"": {
946+
""facetOrdering"": {
947+
""facets"": {
948+
""order"": [""brand"", ""color""]
949+
},
950+
""values"": {
951+
""brand"": {
952+
""order"": [""uniqlo"", ""sony""],
953+
""sortRemainingBy"": ""alpha""
954+
}
955+
}
956+
}
957+
}
958+
}";
959+
var response = JsonConvert.DeserializeObject<SearchResponse<object>>(payload, JsonConfig.AlgoliaJsonSerializerSettings);
960+
961+
Assert.IsNotNull(response.RenderingContent);
962+
Assert.IsNotNull(response.RenderingContent.FacetOrdering);
963+
Assert.IsNotNull(response.RenderingContent.FacetOrdering.Facets);
964+
Assert.IsNotNull(response.RenderingContent.FacetOrdering.Facets.Order);
965+
Assert.True(response.RenderingContent.FacetOrdering.Facets.Order.Contains("brand"));
966+
Assert.True(response.RenderingContent.FacetOrdering.Facets.Order.Contains("color"));
967+
968+
Assert.IsNotNull(response.RenderingContent.FacetOrdering.Values);
969+
Assert.True(response.RenderingContent.FacetOrdering.Values.ContainsKey("brand"));
970+
FacetValuesOrder brandValues = response.RenderingContent.FacetOrdering.Values["brand"];
971+
Assert.True(brandValues.Order.Contains("uniqlo"));
972+
Assert.True(brandValues.Order.Contains("sony"));
973+
Assert.AreEqual("alpha", brandValues.SortRemainingBy);
974+
}
910975
}
911976

912977
public class Product

src/Algolia.Search/Models/Rules/ConsequenceParams.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
using System.Collections.Generic;
25+
using Algolia.Search.Models.Rules;
2526
using Algolia.Search.Models.Search;
2627
using Algolia.Search.Serializer;
2728
using Newtonsoft.Json;
@@ -68,5 +69,11 @@ public class ConsequenceParams : Query
6869
/// Behaves like optionalFilters.
6970
/// </summary>
7071
public List<AutomaticFacetFilter> AutomaticOptionalFacetFilters { get; set; }
72+
73+
/// <summary>
74+
/// Content defining how the search interface should be rendered.
75+
/// This is set via the settings for a default value and can be overridden via rules.
76+
/// </summary>
77+
public RenderingContent RenderingContent { get; set; }
7178
}
7279
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) 2021 Algolia
3+
* http://www.algolia.com/
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
using System.Collections.Generic;
25+
26+
namespace Algolia.Search.Models.Rules
27+
{
28+
/// <summary>
29+
/// Facets and facets values ordering rules container.
30+
/// </summary>
31+
public class FacetOrdering
32+
{
33+
/// <summary>
34+
/// Define or override the way facet attributes are displayed.
35+
/// </summary>
36+
public FacetsOrder Facets { get; set; }
37+
38+
/// <summary>
39+
/// Facet values ordering rule container.
40+
/// </summary>
41+
public Dictionary<string, FacetValuesOrder> Values { get; set; }
42+
}
43+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2021 Algolia
3+
* http://www.algolia.com/
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
using System.Collections.Generic;
25+
using Algolia.Search.Models.Enums;
26+
27+
namespace Algolia.Search.Models.Rules
28+
{
29+
/// <summary>
30+
/// Facet values ordering rule container.
31+
/// </summary>
32+
public class FacetValuesOrder
33+
{
34+
/// <summary>
35+
/// An ordered list of facet values to present.
36+
/// </summary>
37+
public List<string> Order { get; set; }
38+
39+
/// <summary>
40+
/// A constant defining what to do with remaining facet values not included in Order:
41+
/// - "alpha": sort the remaining values in alphanumeric order
42+
/// - "count": sort the remaining values by count in descending order
43+
/// - "hidden": hide the remaining values
44+
/// </summary>
45+
public string SortRemainingBy { get; set; }
46+
}
47+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2021 Algolia
3+
* http://www.algolia.com/
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
using System.Collections.Generic;
25+
26+
namespace Algolia.Search.Models.Rules
27+
{
28+
/// <summary>
29+
/// Define or override the way facet attributes are displayed.
30+
/// </summary>
31+
public class FacetsOrder
32+
{
33+
/// <summary>
34+
/// An ordered list of attributes of facets to present.
35+
/// </summary>
36+
public List<string> Order { get; set; }
37+
}
38+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2021 Algolia
3+
* http://www.algolia.com/
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
namespace Algolia.Search.Models.Rules
25+
{
26+
/// <summary>
27+
/// Content defining how the search interface should be rendered.
28+
/// This is set via the settings for a default value and can be overridden via rules.
29+
/// </summary>
30+
public class RenderingContent
31+
{
32+
/// <summary>
33+
/// Facets and facets values ordering rules container.
34+
/// </summary>
35+
public FacetOrdering FacetOrdering { get; set; }
36+
}
37+
}

src/Algolia.Search/Models/Search/SearchResponse.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
using System.Collections.Generic;
25+
using Algolia.Search.Models.Rules;
2526
using Newtonsoft.Json;
2627

2728
namespace Algolia.Search.Models.Search
@@ -183,5 +184,11 @@ public class SearchResponse<T> where T : class
183184
/// Number of relevant hits to display in case of non-zero relevancyStrictness applied
184185
/// </summary>
185186
public int? NbSortedHits { get; set; }
187+
188+
/// <summary>
189+
/// Content defining how the search interface should be rendered.
190+
/// This is set via the settings for a default value and can be overridden via rules.
191+
/// </summary>
192+
public RenderingContent RenderingContent { get; set; }
186193
}
187194
}

src/Algolia.Search/Models/Settings/IndexSettings.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
*/
2323

2424
using System.Collections.Generic;
25+
using Algolia.Search.Models.Rules;
2526
using Algolia.Search.Serializer;
2627
using Newtonsoft.Json;
2728

@@ -85,12 +86,18 @@ private List<string> AttributesToIndex
8586
public List<string> Replicas { get; set; }
8687

8788
/// <summary>
88-
/// Relevancy score to apply to search in virtual index.
89-
/// Bigger value means less, but more relevant results,
89+
/// Relevancy score to apply to search in virtual index.
90+
/// Bigger value means less, but more relevant results,
9091
/// lesser value - more less relevant results
9192
/// </summary>
9293
public int? RelevancyStrictness { get; set; }
9394

95+
/// <summary>
96+
/// Content defining how the search interface should be rendered.
97+
/// This is set via the settings for a default value and can be overridden via rules.
98+
/// </summary>
99+
public RenderingContent RenderingContent { get; set; }
100+
94101
/// <summary>
95102
/// The primary parameter is automatically added to a replica's settings when the replica is created and cannot be modified.
96103
/// </summary>

src/Algolia.Search/Serializer/QueryConverter.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
namespace Algolia.Search.Serializer
3030
{
3131
/// <summary>
32-
/// Custom serializer for the query object because it must math specific syntax
32+
/// Custom serializer for the query object because it must match specific syntax
3333
/// For more informations regarding the syntax
3434
/// https://www.algolia.com/doc/rest-api/search/#search-endpoints
3535
/// https://www.newtonsoft.com/json/help/html/JsonConverterAttributeClass.htm

0 commit comments

Comments
 (0)