calculate similarity at database level

This commit is contained in:
Luke Pulverenti
2016-06-01 01:50:00 -04:00
parent 0915d1f383
commit e1f562e16f
13 changed files with 411 additions and 257 deletions

View File

@@ -15,6 +15,7 @@ using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
@@ -258,6 +259,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
new MediaStreamColumns(_connection, Logger).AddColumns();
DataExtensions.Attach(_connection, Path.Combine(_config.ApplicationPaths.DataPath, "userdata_v2.db"), "UserDataDb");
dbConnector.BindSimilarityScoreFunction(_connection);
}
private readonly string[] _retriveItemColumns =
@@ -1575,7 +1578,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
return false;
}
private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns)
private string[] GetFinalColumnsToSelect(InternalItemsQuery query, string[] startColumns, IDbCommand cmd)
{
var list = startColumns.ToList();
@@ -1590,6 +1593,45 @@ namespace MediaBrowser.Server.Implementations.Persistence
list.Add("UserDataDb.UserData.rating");
}
if (query.SimilarTo != null)
{
var item = query.SimilarTo;
var builder = new StringBuilder();
builder.Append("GetSimilarityScore(");
builder.Append("@ItemOfficialRating,");
builder.Append("OfficialRating,");
builder.Append("@ItemProductionYear,");
builder.Append("ProductionYear,");
builder.Append("@ItemGenres,");
builder.Append("Genres,");
builder.Append("@ItemTags,");
builder.Append("Tags,");
builder.Append("@ItemKeywords,");
builder.Append("(select group_concat((Select Value from ItemValues where ItemId=Guid and Type=5), '|')),");
builder.Append("@ItemStudios,");
builder.Append("Studios");
builder.Append(") as SimilarityScore");
list.Add(builder.ToString());
cmd.Parameters.Add(cmd, "@ItemOfficialRating", DbType.String).Value = item.OfficialRating;
cmd.Parameters.Add(cmd, "@ItemProductionYear", DbType.Int32).Value = item.ProductionYear ?? -1;
cmd.Parameters.Add(cmd, "@ItemGenres", DbType.String).Value = string.Join("|", item.Genres.ToArray());
cmd.Parameters.Add(cmd, "@ItemTags", DbType.String).Value = string.Join("|", item.Tags.ToArray());
cmd.Parameters.Add(cmd, "@ItemKeywords", DbType.String).Value = string.Join("|", item.Keywords.ToArray());
cmd.Parameters.Add(cmd, "@ItemStudios", DbType.String).Value = string.Join("|", item.Studios.ToArray());
var excludeIds = query.ExcludeItemIds.ToList();
excludeIds.Add(item.Id.ToString("N"));
query.ExcludeItemIds = excludeIds.ToArray();
}
return list.ToArray();
}
@@ -1616,7 +1658,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems";
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems";
cmd.CommandText += GetJoinUserDataText(query);
if (EnableJoinUserData(query))
@@ -1706,7 +1748,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns)) + " from TypedBaseItems";
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, _retriveItemColumns, cmd)) + " from TypedBaseItems";
cmd.CommandText += GetJoinUserDataText(query);
if (EnableJoinUserData(query))
@@ -1789,6 +1831,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
private string GetOrderByText(InternalItemsQuery query)
{
if (query.SimilarTo != null)
{
if (query.SortBy == null || query.SortBy.Length == 0)
{
query.SortBy = new[] { "SimilarityScore", "Random" };
query.SortOrder = SortOrder.Descending;
}
}
if (query.SortBy == null || query.SortBy.Length == 0)
{
return string.Empty;
@@ -1879,7 +1930,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems";
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems";
cmd.CommandText += GetJoinUserDataText(query);
if (EnableJoinUserData(query))
@@ -2022,7 +2073,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
using (var cmd = _connection.CreateCommand())
{
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" })) + " from TypedBaseItems";
cmd.CommandText = "select " + string.Join(",", GetFinalColumnsToSelect(query, new[] { "guid" }, cmd)) + " from TypedBaseItems";
var whereClauses = GetWhereClauses(query, cmd);
cmd.CommandText += GetJoinUserDataText(query);
@@ -2148,24 +2199,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
else
{
if (query.IsMovie.Value)
{
var typeClauses = new List<string>();
var typeIndex = 0;
foreach (var type in alternateTypes)
{
var paramName = "@AlternateType" + typeIndex.ToString(CultureInfo.InvariantCulture);
typeClauses.Add("Type=" + paramName);
cmd.Parameters.Add(cmd, paramName, DbType.String).Value = type;
typeIndex++;
}
whereClauses.Add("(IsMovie=@IsMovie OR " + string.Join(" OR ", typeClauses.ToArray()) + ")");
}
else
{
whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)");
}
whereClauses.Add("(IsMovie is null OR IsMovie=@IsMovie)");
}
cmd.Parameters.Add(cmd, "@IsMovie", DbType.Boolean).Value = query.IsMovie;
}