Skip to content

Commit 5c1a04a

Browse files
feat(HitsTracker): add automatic object ids chunking (#284)
1 parent 2b8eced commit 5c1a04a

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

Sources/InstantSearchCore/Tracker/HitsTracker.swift

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ public class HitsTracker: InsightsTracker {
2929
/// An optional identifier for the search query.
3030
internal var queryID: QueryID?
3131

32+
/// Max object IDs per event
33+
private let maxObjectIDsCount = 20
34+
3235
/// Initializes a new instance of the `HitsTracker` class with the specified event name, `TrackableSearcher`, and `Insights` object.
3336
///
3437
/// - Parameters:
@@ -99,12 +102,14 @@ public extension HitsTracker {
99102
eventName: EventName? = nil) {
100103
guard isEnabled else { return }
101104
guard let queryID = queryID else { return }
102-
tracker.clickedAfterSearch(eventName: eventName ?? self.eventName,
103-
indexName: searcher.indexName,
104-
objectIDsWithPositions: Array(zip(hits.map(\.objectID), positions)),
105-
queryID: queryID,
106-
timestamp: .none,
107-
userToken: .none)
105+
for objectIDsWithPositions in Array(zip(hits.map(\.objectID), positions)).chunk(into: maxObjectIDsCount) {
106+
tracker.clickedAfterSearch(eventName: eventName ?? self.eventName,
107+
indexName: searcher.indexName,
108+
objectIDsWithPositions: objectIDsWithPositions,
109+
queryID: queryID,
110+
timestamp: .none,
111+
userToken: .none)
112+
}
108113
}
109114

110115
/// Tracks a conversion event for the specified search result.
@@ -127,12 +132,14 @@ public extension HitsTracker {
127132
eventName: EventName? = nil) {
128133
guard isEnabled else { return }
129134
guard let queryID = queryID else { return }
130-
tracker.convertedAfterSearch(eventName: eventName ?? self.eventName,
131-
indexName: searcher.indexName,
132-
objectIDs: hits.map(\.objectID),
133-
queryID: queryID,
134-
timestamp: .none,
135-
userToken: .none)
135+
for objectIDs in hits.map(\.objectID).chunk(into: maxObjectIDsCount) {
136+
tracker.convertedAfterSearch(eventName: eventName ?? self.eventName,
137+
indexName: searcher.indexName,
138+
objectIDs: objectIDs,
139+
queryID: queryID,
140+
timestamp: .none,
141+
userToken: .none)
142+
}
136143
}
137144

138145
/// Tracks a view event for the specified search result.
@@ -154,10 +161,20 @@ public extension HitsTracker {
154161
func trackView<Record: Codable>(for hits: [Hit<Record>],
155162
eventName: EventName? = nil) {
156163
guard isEnabled else { return }
157-
tracker.viewed(eventName: eventName ?? self.eventName,
158-
indexName: searcher.indexName,
159-
objectIDs: hits.map(\.objectID),
160-
timestamp: .none,
161-
userToken: .none)
164+
for objectIDs in hits.map(\.objectID).chunk(into: maxObjectIDsCount) {
165+
tracker.viewed(eventName: eventName ?? self.eventName,
166+
indexName: searcher.indexName,
167+
objectIDs: objectIDs,
168+
timestamp: .none,
169+
userToken: .none)
170+
}
162171
}
163172
}
173+
174+
fileprivate extension Array {
175+
func chunk(into size: Int) -> [[Element]] {
176+
return stride(from: 0, to: count, by: size).map {
177+
Array(self[$0 ..< Swift.min($0 + size, count)])
178+
}
179+
}
180+
}

0 commit comments

Comments
 (0)