72 lines
2.2 KiB
Kotlin
72 lines
2.2 KiB
Kotlin
package com.rssuper.search
|
|
|
|
import com.rssuper.database.daos.FeedItemDao
|
|
import com.rssuper.database.entities.FeedItemEntity
|
|
|
|
/**
|
|
* SearchResultProvider - Provides search results from the database
|
|
*/
|
|
class SearchResultProvider(
|
|
private val feedItemDao: FeedItemDao
|
|
) {
|
|
suspend fun search(query: String, limit: Int = 20): List<SearchResult> {
|
|
// Use FTS query to search feed items
|
|
val results = feedItemDao.searchByFts(query, limit)
|
|
|
|
return results.mapIndexed { index, item ->
|
|
SearchResult(
|
|
feedItem = item,
|
|
relevanceScore = calculateRelevance(query, item, index),
|
|
highlight = generateHighlight(item)
|
|
)
|
|
}
|
|
}
|
|
|
|
suspend fun searchBySubscription(query: String, subscriptionId: String, limit: Int = 20): List<SearchResult> {
|
|
val results = feedItemDao.searchByFts(query, limit)
|
|
|
|
return results.filter { it.subscriptionId == subscriptionId }.mapIndexed { index, item ->
|
|
SearchResult(
|
|
feedItem = item,
|
|
relevanceScore = calculateRelevance(query, item, index),
|
|
highlight = generateHighlight(item)
|
|
)
|
|
}
|
|
}
|
|
|
|
private fun calculateRelevance(query: String, item: FeedItemEntity, position: Int): Float {
|
|
val queryLower = query.lowercase()
|
|
var score = 0.0f
|
|
|
|
// Title match (highest weight)
|
|
if (item.title.lowercase().contains(queryLower)) {
|
|
score += 1.0f
|
|
}
|
|
|
|
// Author match
|
|
if (item.author?.lowercase()?.contains(queryLower) == true) {
|
|
score += 0.5f
|
|
}
|
|
|
|
// Position bonus (earlier results are more relevant)
|
|
score += (1.0f / (position + 1)) * 0.3f
|
|
|
|
return score.coerceIn(0.0f, 1.0f)
|
|
}
|
|
|
|
private fun generateHighlight(item: FeedItemEntity): String? {
|
|
val maxLength = 200
|
|
var text = item.title
|
|
|
|
if (item.description?.isNotEmpty() == true) {
|
|
text += " ${item.description}"
|
|
}
|
|
|
|
if (text.length > maxLength) {
|
|
text = text.substring(0, maxLength) + "..."
|
|
}
|
|
|
|
return text
|
|
}
|
|
}
|