Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1871,15 +1871,26 @@ public partial class FacetResult : System.Collections.Generic.IEnumerable<System
{
internal FacetResult() { }
public long? Count { get { throw null; } }
public Azure.Search.Documents.Models.FacetType FacetType { get { throw null; } }
public object From { get { throw null; } }
public object this[string key] { get { throw null; } }
public System.Collections.Generic.IEnumerable<string> Keys { get { throw null; } }
int System.Collections.Generic.IReadOnlyCollection<System.Collections.Generic.KeyValuePair<System.String,System.Object>>.Count { get { throw null; } }
public object To { get { throw null; } }
public object Value { get { throw null; } }
public System.Collections.Generic.IEnumerable<object> Values { get { throw null; } }
public Azure.Search.Documents.Models.RangeFacetResult<T> AsRangeFacetResult<T>() where T : struct { throw null; }
public Azure.Search.Documents.Models.ValueFacetResult<T> AsValueFacetResult<T>() { throw null; }
public bool ContainsKey(string key) { throw null; }
public System.Collections.Generic.IEnumerator<System.Collections.Generic.KeyValuePair<string, object>> GetEnumerator() { throw null; }
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw null; }
public bool TryGetValue(string key, out object value) { throw null; }
}
public enum FacetType
{
Value = 0,
Range = 1,
}
public enum IndexActionType
{
Upload = 0,
Expand Down Expand Up @@ -1928,6 +1939,13 @@ internal IndexingResult() { }
public int Status { get { throw null; } }
public bool Succeeded { get { throw null; } }
}
public partial class RangeFacetResult<T> where T : struct
{
public RangeFacetResult(long count, T? from, T? to) { }
public long Count { get { throw null; } }
public T? From { get { throw null; } }
public T? To { get { throw null; } }
}
public partial class SearchDocument : System.Dynamic.DynamicObject, System.Collections.Generic.ICollection<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IEnumerable<System.Collections.Generic.KeyValuePair<string, object>>, System.Collections.IEnumerable
{
public SearchDocument() { }
Expand Down Expand Up @@ -2000,4 +2018,10 @@ internal SuggestResults() { }
public double? Coverage { get { throw null; } }
public System.Collections.Generic.IList<Azure.Search.Documents.Models.SearchSuggestion<T>> Results { get { throw null; } }
}
public partial class ValueFacetResult<T>
{
public ValueFacetResult(long count, T value) { }
public long Count { get { throw null; } }
public T Value { get { throw null; } }
}
}
80 changes: 80 additions & 0 deletions sdk/search/Azure.Search.Documents/src/Models/FacetResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Search.Documents.Models
{
public partial class FacetResult
{
/// <summary>
/// Gets the type of this facet. Value facets count documents with a
/// particular field value and Range facets count documents with a
/// field value in a particular range.
/// </summary>
public FacetType FacetType => (Value != null) ? FacetType.Value : FacetType.Range;

/// <summary>
/// Gets the value of the facet, or the inclusive lower bound if it's
/// an interval facet.
/// </summary>
public object Value => GetValue(Constants.ValueKey);

/// <summary>
/// Gets a value indicating the inclusive lower bound of the facet's
/// range, or null to indicate that there is no lower bound (i.e. --
/// for the first bucket).
/// </summary>
public object From => GetValue(Constants.FromKey);

/// <summary>
/// Gets a value indicating the exclusive upper bound of the facet's
/// range, or null to indicate that there is no upper bound (i.e. --
/// for the last bucket).
/// </summary>
public object To => GetValue(Constants.ToKey);

/// <summary>
/// Get the value of a key like "value" or return null if not found.
/// </summary>
/// <param name="key">The name of the key to lookup.</param>
/// <returns>The value of the key or null.</returns>
private object GetValue(string key) =>
AdditionalProperties.TryGetValue(key, out object value) ? value : null;

/// <summary>
/// Attempts to convert the facet to a range facet of the given type.
/// </summary>
/// <typeparam name="T">
/// A type that matches the type of the field to which the facet was
/// applied. Valid types include <see cref="DateTimeOffset"/>,
/// <see cref="Double"/>, and <see cref="Int64"/>.
/// </typeparam>
/// <returns>A new strongly-typed range facet instance.</returns>
/// <exception cref="InvalidCastException">
/// This instance is not a range facet of the given type.
/// </exception>
public RangeFacetResult<T> AsRangeFacetResult<T>() where T : struct
{
if (FacetType != FacetType.Range) { throw new InvalidCastException(); }
return new RangeFacetResult<T>(Count.GetValueOrDefault(), (T?)From, (T?)To);
}

/// <summary>
/// Attempts to convert the facet to a value facet of the given type.
/// </summary>
/// <typeparam name="T">
/// A type that matches the type of the field to which the facet was
/// applied.
/// </typeparam>
/// <returns>A new strongly-typed value facet instance.</returns>
/// <exception cref="InvalidCastException">
/// This instance is not a value facet of the given type.
/// </exception>
public ValueFacetResult<T> AsValueFacetResult<T>()
{
if (FacetType != FacetType.Value) { throw new InvalidCastException(); }
return new ValueFacetResult<T>(Count.GetValueOrDefault(), (T)Value);
}
}
}
21 changes: 21 additions & 0 deletions sdk/search/Azure.Search.Documents/src/Models/FacetType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Azure.Search.Documents.Models
{
/// <summary>
/// Specifies the type of a facet query result.
/// </summary>
public enum FacetType
{
/// <summary>
/// The facet counts documents with a particular field value.
/// </summary>
Value = 0,

/// <summary>
/// The facet counts documents with a field value in a particular range.
/// </summary>
Range
}
}
63 changes: 63 additions & 0 deletions sdk/search/Azure.Search.Documents/src/Models/RangeFacetResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Search.Documents.Models
{
/// <summary>
/// A single bucket of a range facet query result that reports the number
/// of documents with a field value falling within a particular range.
/// </summary>
/// <typeparam name="T">
/// A type that matches the type of the field to which the facet was
/// applied. Valid types include <see cref="DateTimeOffset"/>,
/// <see cref="Double"/>, and <see cref="Int64"/>.
/// </typeparam>
public class RangeFacetResult<T> where T : struct
{
/// <summary>
/// Gets the approximate count of documents falling within the bucket
/// described by this facet.
/// </summary>
public long Count { get; }

/// <summary>
/// Gets a value indicating the inclusive lower bound of the facet's
/// range, or <c>null</c> to indicate that there is no lower bound
/// (for the first bucket).
/// </summary>
public T? From { get; }

/// <summary>
/// Gets a value indicating the exclusive upper bound of the facet's
/// range, or <c>null</c> to indicate that there is no upper bound
/// (for the last bucket).
/// </summary>
public T? To { get; }

/// <summary>
/// Creates a new instance of the RangeFacetResult class.
/// </summary>
/// <param name="count">
/// The approximate count of documents falling within the bucket
/// described by this facet.
/// </param>
/// <param name="from">
/// A value indicating the inclusive lower bound of the facet's range,
/// or <c>null</c> to indicate that there is no lower bound (for the
/// first bucket).
/// </param>
/// <param name="to">
/// A value indicating the exclusive upper bound of the facet's range,
/// or <c>null</c> to indicate that there is no upper bound (for the
/// last bucket).
/// </param>
public RangeFacetResult(long count, T? from, T? to)
{
From = from;
To = to;
Count = count;
}
}
}
48 changes: 48 additions & 0 deletions sdk/search/Azure.Search.Documents/src/Models/ValueFacetResult.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;

namespace Azure.Search.Documents.Models
{
/// <summary>
/// A single bucket of a simple or interval facet query result that reports
/// the number of documents with a field falling within a particular
/// interval or having a specific value.
/// </summary>
/// <typeparam name="T">
/// A type that matches the type of the field to which the facet was
/// applied.
/// </typeparam>
public class ValueFacetResult<T>
{
/// <summary>
/// Gets the approximate count of documents falling within the bucket
/// described by this facet.
/// </summary>
public long Count { get; }

/// <summary>
/// Gets the value of the facet, or the inclusive lower bound if it's
/// an interval facet.
/// </summary>
public T Value { get; }

/// <summary>
/// Creates a new instance of the ValueFacetResult class.
/// </summary>
/// <param name="count">
/// The approximate count of documents falling within the bucket
/// described by this facet.
/// </param>
/// <param name="value">
/// The value of the facet, or the inclusive lower bound if it's an
/// interval facet.
/// </param>
public ValueFacetResult(long count, T value)
{
Value = value;
Count = count;
}
}
}
10 changes: 10 additions & 0 deletions sdk/search/Azure.Search.Documents/src/Utilities/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ internal static class Constants
/// </summary>
public const string CountKey = "count";

/// <summary>
/// The to key.
/// </summary>
public const string FromKey = "from";

/// <summary>
/// The from key.
/// </summary>
public const string ToKey = "to";

/// <summary>
/// Initial ArrayPool rental size for copying unseekable streams in
/// our sync <see cref="JsonExtensions.Deserialize{T}"/> method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,20 @@ await AssertKeysContains(
GetFacetsForField(response.Value.Facets, "lastRenovationDate", 2),
MakeRangeFacet(count: 5, from: null, to: new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero)),
MakeRangeFacet(count: 2, from: new DateTimeOffset(2000, 1, 1, 0, 0, 0, TimeSpan.Zero), to: null));

// Check strongly typed range facets
ICollection<FacetResult> facets = GetFacetsForField(response.Value.Facets, "rooms/baseRate", 4);
RangeFacetResult<double> first = facets.ElementAt(0).AsRangeFacetResult<double>();
Assert.AreEqual(1, first.Count);
Assert.AreEqual(5, first.To);
RangeFacetResult<double> second = facets.ElementAt(1).AsRangeFacetResult<double>();
Assert.AreEqual(1, second.Count);
Assert.AreEqual(5, second.From);
Assert.AreEqual(8, second.To);
RangeFacetResult<double> last = facets.ElementAt(3).AsRangeFacetResult<double>();
Assert.AreEqual(null, first.From);
Assert.AreEqual(null, last.To);

}

[Test]
Expand Down Expand Up @@ -600,6 +614,15 @@ await AssertKeysContains(
MakeValueFacet(1, "restaurant"),
MakeValueFacet(1, "view"),
MakeValueFacet(4, "wifi"));

// Check strongly typed value facets
ICollection<FacetResult> facets = GetFacetsForField(response.Value.Facets, "rating", 2);
ValueFacetResult<int> first = facets.ElementAt(0).AsValueFacetResult<int>();
Assert.AreEqual(5, first.Value);
Assert.AreEqual(1, first.Count);
ValueFacetResult<int> second = facets.ElementAt(1).AsValueFacetResult<int>();
Assert.AreEqual(4, second.Value);
Assert.AreEqual(4, second.Count);
}

[Test]
Expand Down