From ceac69237aa5bb6e0b7fc5ffd648db53256143e4 Mon Sep 17 00:00:00 2001 From: only1question Date: Thu, 14 Apr 2022 14:34:39 +0300 Subject: [PATCH 01/12] fixed ParseFeedRequest for different feeds --- src/.idea/codeStyles/Project.xml | 2 +- src/pocketdb/web/PocketContentRpc.cpp | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/.idea/codeStyles/Project.xml b/src/.idea/codeStyles/Project.xml index 213c5ea87..550d10440 100644 --- a/src/.idea/codeStyles/Project.xml +++ b/src/.idea/codeStyles/Project.xml @@ -23,7 +23,7 @@ - + diff --git a/src/pocketdb/web/PocketContentRpc.cpp b/src/pocketdb/web/PocketContentRpc.cpp index 3bc12eadb..35ae6435a 100644 --- a/src/pocketdb/web/PocketContentRpc.cpp +++ b/src/pocketdb/web/PocketContentRpc.cpp @@ -97,18 +97,19 @@ namespace PocketWeb::PocketWebRpc } } - // feed's address if (request.params.size() > 10) { - RPCTypeCheckArgument(request.params[10], UniValue::VSTR); - address_feed = request.params[10].get_str(); - if (!address_feed.empty()) + // feed's address + if (request.params[10].isStr()) { - CTxDestination dest = DecodeDestination(address_feed); + address_feed = request.params[10].get_str(); + if (!address_feed.empty()) + { + CTxDestination dest = DecodeDestination(address_feed); - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address_feed); - } + if (!IsValidDestination(dest)) + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address_feed); + } } } From 0910379d684687d57d7dd8166518b0ffce6b977d Mon Sep 17 00:00:00 2001 From: only1question Date: Thu, 14 Apr 2022 14:45:52 +0300 Subject: [PATCH 02/12] changed sorting param in GetTopFeed --- src/pocketdb/repositories/web/WebRpcRepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketdb/repositories/web/WebRpcRepository.cpp b/src/pocketdb/repositories/web/WebRpcRepository.cpp index 852477cfb..2285553d7 100644 --- a/src/pocketdb/repositories/web/WebRpcRepository.cpp +++ b/src/pocketdb/repositories/web/WebRpcRepository.cpp @@ -2884,7 +2884,7 @@ namespace PocketDb ) )sql"; } - sql += " order by t.Id desc "; + sql += " order by cr.Value desc "; sql += " limit ? "; // --------------------------------------------- From 32cdde58caecec0e4d5058704b322a69dca49319 Mon Sep 17 00:00:00 2001 From: only1question Date: Thu, 14 Apr 2022 15:06:17 +0300 Subject: [PATCH 03/12] added several methods into cache --- src/pocketdb/web/PocketContentRpc.cpp | 1 + src/rpc/cache.h | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/pocketdb/web/PocketContentRpc.cpp b/src/pocketdb/web/PocketContentRpc.cpp index 35ae6435a..99098795c 100644 --- a/src/pocketdb/web/PocketContentRpc.cpp +++ b/src/pocketdb/web/PocketContentRpc.cpp @@ -110,6 +110,7 @@ namespace PocketWeb::PocketWebRpc if (!IsValidDestination(dest)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address_feed); } + } } } diff --git a/src/rpc/cache.h b/src/rpc/cache.h index 79514bd22..c6de8772c 100644 --- a/src/rpc/cache.h +++ b/src/rpc/cache.h @@ -36,6 +36,7 @@ class RPCCache "gethierarchicalfeed", "gethierarchicalstrip", "gethotposts", + "gettopfeed", "getuserprofile", "getprofilefeed", "getsubscribesfeed", @@ -50,6 +51,7 @@ class RPCCache "getusersubscribes", "getusersubscribers", "getuserblockings", + "gettopaccounts", "getaddressscores", "getpostscores", "getstatisticbyhours", @@ -59,6 +61,8 @@ class RPCCache "getrecomendedaccountsbytags", "getrecomendedcontentsbyscoresonsimilarcontents", "getrecommendedcontentbycontentid", + "getrecommendedcontentbyaddress", + "getrecommendedaccountbyaddress", "getaddressinfo", "getcompactblock", "getlastblocks", From 450a4db19b6f2bf9d7f269c2d50171af79fee46b Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 09:29:33 +0300 Subject: [PATCH 04/12] acceleration GetTopFeed --- src/pocketdb/repositories/web/WebRpcRepository.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pocketdb/repositories/web/WebRpcRepository.cpp b/src/pocketdb/repositories/web/WebRpcRepository.cpp index 2285553d7..5463913b9 100644 --- a/src/pocketdb/repositories/web/WebRpcRepository.cpp +++ b/src/pocketdb/repositories/web/WebRpcRepository.cpp @@ -2826,19 +2826,19 @@ namespace PocketDb string langFilter; if (!lang.empty()) - langFilter += " join Payload p indexed by Payload_String1_TxHash on p.TxHash = t.Hash and p.String1 = ? "; + langFilter += " cross join Payload p indexed by Payload_String1_TxHash on p.TxHash = t.Hash and p.String1 = ? "; string sql = R"sql( select t.Id - from Transactions t indexed by Transactions_Last_Id_Height + from Transactions t indexed by Transactions_Type_Last_Height_Id - join Ratings cr indexed by Ratings_Type_Id_Last_Value + cross join Ratings cr indexed by Ratings_Type_Id_Last_Value on cr.Type = 2 and cr.Last = 1 and cr.Id = t.Id and cr.Value > 0 )sql" + langFilter + R"sql( - join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id on u.Type in (100) and u.Last = 1 and u.Height > 0 and u.String1 = t.String1 left join Ratings ur indexed by Ratings_Type_Id_Last_Height From 2cc0c92700dfb094131eaf34cba6fd04e2bc542f Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 10:33:43 +0300 Subject: [PATCH 05/12] Fixed typo in GetTopFeed --- src/pocketdb/repositories/web/WebRpcRepository.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pocketdb/repositories/web/WebRpcRepository.cpp b/src/pocketdb/repositories/web/WebRpcRepository.cpp index 5463913b9..505d54870 100644 --- a/src/pocketdb/repositories/web/WebRpcRepository.cpp +++ b/src/pocketdb/repositories/web/WebRpcRepository.cpp @@ -2846,7 +2846,7 @@ namespace PocketDb where t.Type in )sql" + contentTypesWhere + R"sql( and t.Last = 1 - and t.String3 is null + --and t.String3 is null and t.Height > ? and t.Height <= ? From 839d5081192296b400daeaa4220eec9db209c958 Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 11:21:30 +0300 Subject: [PATCH 06/12] Removed old non-used methods --- .../repositories/web/SearchRepository.cpp | 500 ------------------ .../repositories/web/SearchRepository.h | 7 - src/pocketdb/web/PocketRpc.cpp | 9 - src/pocketdb/web/SearchRpc.cpp | 260 --------- src/pocketdb/web/SearchRpc.h | 30 -- 5 files changed, 806 deletions(-) diff --git a/src/pocketdb/repositories/web/SearchRepository.cpp b/src/pocketdb/repositories/web/SearchRepository.cpp index 4bf789f07..1d61d53a5 100644 --- a/src/pocketdb/repositories/web/SearchRepository.cpp +++ b/src/pocketdb/repositories/web/SearchRepository.cpp @@ -231,506 +231,6 @@ namespace PocketDb return result; } - UniValue SearchRepository::GetRecomendedAccountsBySubscriptions(const string& address, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (address.empty()) - return result; - - string sql = R"sql( - select - recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select - t.String2 address - from Transactions t indexed by Transactions_Type_Last_String1_String2_Height - where t.Last = 1 - and t.Type in (302,303) - and t.Height is not null - and t.String2 != ? - and t.String1 in (select s.String1 - from Transactions s indexed by Transactions_Type_Last_String2_Height - where s.Type in (302,303) - and s.Last = 1 - and s.Height is not null - and s.String2 = ?) - group by t.String2 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash - - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - TryBindStatementText(stmt, i++, address); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - - UniValue SearchRepository::GetRecomendedAccountsByScoresOnSimilarAccounts(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (address.empty()) - return result; - - string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); - - string sql = R"sql( - select recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select - tOtherContents.String1 as address - from Transactions tOtherContents - indexed by Transactions_Type_Last_String1_String2_Height - where tOtherContents.String2 in ( - select tOtherLikes.String2 as OtherLikedContent - from Transactions tOtherlikes - where tOtherLikes.String1 in ( - select tLikes.String1 as Liker - from Transactions tLikes - where tLikes.String2 in ( - select tContents.String2 as BloggerContent - from Transactions tContents - where tContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tContents.Last = 1 - and tContents.String1 = ? - and tContents.Height >= ? - ) - and tLikes.Type in (300) - and tLikes.Last in (1, 0) - and tLikes.Int1 > 3 - and tLikes.Height >= ? - ) - and tOtherLikes.Type in (300) - and tOtherLikes.Last in (1, 0) - and tOtherLikes.Int1 > 3 - and tOtherLikes.Height >= ? - ) - and tOtherContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tOtherContents.String1 != ? - and tOtherContents.Last = 1 - and tOtherContents.Height >= ? - group by tOtherContents.String1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id - on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - - UniValue SearchRepository::GetRecomendedAccountsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (address.empty()) - return result; - - string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); - - string sql = R"sql( - select recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select - tOtherContents.String1 as address - from Transactions tOtherContents - indexed by Transactions_Type_Last_String2_Height - where tOtherContents.String2 in ( - select tOtherLikes.String2 as OtherLikedContent - from Transactions tOtherlikes - where tOtherLikes.String1 in ( - select tLikes.String1 as Liker - from Transactions tLikes - where tLikes.String2 in ( - select tAddressLikes.String2 as ContentsLikedByAddress - from Transactions tAddressLikes - where tAddressLikes.String1 = ? - and tAddressLikes.Type in (300) - and tAddressLikes.Last in (1, 0) - and tAddressLikes.Int1 > 3 - and tAddressLikes.Height >= ? - ) - and tLikes.Type in (300) - and tLikes.Last in (1, 0) - and tLikes.Int1 > 3 - and tLikes.Height >= ? - ) - and tOtherLikes.Type in (300) - and tOtherLikes.Last in (1, 0) - and tOtherLikes.Int1 > 3 - and tOtherLikes.Height >= ? - ) - and tOtherContents.Type in ( )sql" + contentTypesFilter + R"sql( ) - and tOtherContents.String1 != ? - and tOtherContents.Last = 1 - and tOtherContents.Height >= ? - group by tOtherContents.String1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - - UniValue SearchRepository::GetRecomendedAccountsByTags(const vector& tags, int nHeight, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (tags.empty()) - return result; - - string tagsFilter = join(vector(tags.size(), "?"), ","); - - string sql = R"sql( - select - recommendation.address, - p.String2 as name, - p.String3 as avatar - - , ifnull(( - select r.Value - from Ratings r indexed by Ratings_Type_Id_Last_Height - where r.Type=0 and r.Id=u.Id and r.Last=1) - ,0) as Reputation - - , ( - select count(*) - from Transactions subs indexed by Transactions_Type_Last_String2_Height - where subs.Type in (302,303) and subs.Height is not null and subs.Last = 1 and subs.String2 = u.String1 - ) as SubscribersCount - from ( - select authors.string1 address - from ( - select c.String1 - from Transactions sc indexed by Transactions_Type_Last_Height_Id - cross join Transactions c indexed by Transactions_Type_Last_String2_Height - on c.String2 = sc.String2 and c.Type in (200, 201, 202) and c.Height > 0 and c.Last = 1 - and c.id in (select tm.ContentId - from web.Tags tag indexed by Tags_Lang_Value_Id - join web.TagsMap tm indexed by TagsMap_TagId_ContentId - on tag.Id = tm.TagId - where tag.Value in ( )sql" + join(vector(tags.size(), "?"), ",") + R"sql( )) - where sc.Type in (300) - and sc.Last in (0, 1) - and sc.Height > ? - and sc.Int1 = 5 - ) authors - group by authors.string1 - order by count(*) desc - limit ? - )recommendation - cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id on u.String1 = recommendation.address - and u.Type in (100,101,102) - and u.Last=1 - and u.Height is not null - cross join Payload p on p.TxHash = u.Hash - - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - for (const auto& tag: tags) - TryBindStatementText(stmt, i++, tag); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("address", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 1); ok) record.pushKV("name", value); - if (auto[ok, value] = TryGetColumnString(*stmt, 2); ok) record.pushKV("avatar", value); - if (auto[ok, value] = TryGetColumnInt(*stmt, 3); ok) record.pushKV("reputation", value / 10.0); - if (auto[ok, value] = TryGetColumnInt(*stmt, 4); ok) record.pushKV("subscribers_count", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - - UniValue SearchRepository::GetRecomendedContentsByScoresOnSimilarContents(const string& contentid, const vector& contentTypes, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (contentid.empty()) - return result; - - string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); - - string sql = R"sql( - select OtherRaters.String2 OtherScoredContent, count(*) cnt - from Transactions OtherRaters indexed by Transactions_Type_Last_String1_Height_Id - cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height - on OtherRaters.String2 = Contents.String2 and Contents.Last = 1 and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) and Contents.Height > 0 - where OtherRaters.Type in (300) - and OtherRaters.Int1 > 3 - and OtherRaters.Last in (1, 0) - and OtherRaters.Height >= (select Height - from Transactions indexed by Transactions_Type_Last_String2_Height - where Type in ( )sql" + contentTypesFilter + R"sql( ) - and String2 = ? - and Last = 1) - ? - and OtherRaters.String1 in ( - select String1 as Rater - from Transactions Raters indexed by Transactions_Type_Last_String2_Height - where Raters.Type in (300) - and Raters.Int1 > 3 - and Raters.String2 = ? - and Raters.Last in (1, 0) - ) - and OtherRaters.String2 != ? - group by OtherRaters.String2 - order by count(*) desc - limit ? - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, contentid); - TryBindStatementInt(stmt, i++, depth); - TryBindStatementText(stmt, i++, contentid); - TryBindStatementText(stmt, i++, contentid); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("contentid", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - - UniValue SearchRepository::GetRecomendedContentsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth, int cntOut) - { - auto func = __func__; - UniValue result(UniValue::VARR); - - if (address.empty()) - return result; - - string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); - - string sql = R"sql( - select OtherRaters.String2 as OtherScoredContent, count(*) cnt - from Transactions OtherRaters indexed by Transactions_Type_Last_String1_Height_Id - cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height - on OtherRaters.String2 = Contents.String2 and Contents.Last = 1 and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) and Contents.Height > 0 - where OtherRaters.String1 in ( - select Scores.String1 as Rater - from Transactions Scores indexed by Transactions_Type_Last_String2_Height - where Scores.String2 in ( - select addressScores.String2 as ContentsScoredByAddress - from Transactions addressScores indexed by Transactions_Type_Last_String1_Height_Id - where addressScores.String1 = ? - and addressScores.Type in (300) - and addressScores.Last in (1, 0) - and addressScores.Int1 > 3 - and addressScores.Height >= ? - ) - and Scores.Type in (300) - and Scores.Last in (1, 0) - and Scores.Int1 > 3 - and Scores.Height >= ? - ) - and OtherRaters.Type in (300) - and OtherRaters.Last in (1, 0) - and OtherRaters.Int1 > 3 - and OtherRaters.Height >= ? - group by OtherRaters.String2 - order by count(*) desc - limit ? - )sql"; - - TryTransactionStep(__func__, [&]() - { - auto stmt = SetupSqlStatement(sql); - - int i = 1; - for (const auto& contenttype: contentTypes) - TryBindStatementInt(stmt, i++, contenttype); - TryBindStatementText(stmt, i++, address); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, nHeight - depth); - TryBindStatementInt(stmt, i++, cntOut); - - while (sqlite3_step(*stmt) == SQLITE_ROW) - { - UniValue record(UniValue::VOBJ); - if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) record.pushKV("contentid", value); - result.push_back(record); - } - - FinalizeSqlStatement(*stmt); - }); - - return result; - } - vector SearchRepository::GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) { auto func = __func__; diff --git a/src/pocketdb/repositories/web/SearchRepository.h b/src/pocketdb/repositories/web/SearchRepository.h index 2ee3f07f7..5b32cf396 100644 --- a/src/pocketdb/repositories/web/SearchRepository.h +++ b/src/pocketdb/repositories/web/SearchRepository.h @@ -34,13 +34,6 @@ namespace PocketDb vector SearchUsersOld(const SearchRequest& request); vector SearchUsers(const string& keyword); - UniValue GetRecomendedAccountsBySubscriptions(const string& address, int cntOut = 10); - UniValue GetRecomendedAccountsByScoresOnSimilarAccounts(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedAccountsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedAccountsByTags(const vector& tags, int nHeight, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedContentsByScoresOnSimilarContents(const string& contentid, const vector& contentTypes, int depth = 1000, int cntOut = 10); - UniValue GetRecomendedContentsByScoresFromAddress(const string& address, const vector& contentTypes, int nHeight, int depth = 1000, int cntOut = 10); - vector GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); vector GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); vector GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut); diff --git a/src/pocketdb/web/PocketRpc.cpp b/src/pocketdb/web/PocketRpc.cpp index cc24b2792..36bc6946a 100644 --- a/src/pocketdb/web/PocketRpc.cpp +++ b/src/pocketdb/web/PocketRpc.cpp @@ -32,15 +32,6 @@ static const CRPCCommand commands[] = {"search", "searchusers", &SearchUsers, {"keyword", "fieldtypes", "orderbyrank"}}, // Recomendations - // TODO (o1q): Remove below methods when the client gui switches to new methods - {"search", "getrecomendedaccountsbysubscriptions", &GetRecomendedAccountsBySubscriptions, {"address", "count"}}, - {"search", "getrecomendedaccountsbyscoresonsimilaraccounts", &GetRecomendedAccountsByScoresOnSimilarAccounts, {"address", "contenttypes", "height", "depth", "count"}}, - {"search", "getrecomendedaccountsbyscoresfromaddress", &GetRecomendedAccountsByScoresFromAddress, {"address", "contenttypes", "height", "depth", "count"}}, - {"search", "getrecomendedaccountsbytags", &GetRecomendedAccountsByTags, {"tags", "count"}}, - {"search", "getrecomendedcontentsbyscoresonsimilarcontents", &GetRecomendedContentsByScoresOnSimilarContents, {"contentid", "contenttypes", "depth", "count"}}, - {"search", "getrecomendedcontentsbyscoresfromaddress", &GetRecomendedContentsByScoresFromAddress, {"address", "contenttypes", "height", "depth", "count"}}, - // TODO (o1q): Remove above methods when the client gui switches to new (below) methods - {"search", "getrecommendedcontentbycontentid", &GetRecommendedContentByContentId, {"contentid", "address", "contenttypes", "lang", "count"}}, {"search", "getrecommendedcontentbyaddress", &GetRecommendedContentByAddress, {"address", "addressExclude", "contenttypes", "lang", "count"}}, {"search", "getrecommendedaccountbyaddress", &GetRecommendedAccountByAddress, {"address", "addressExclude", "contenttypes", "lang", "count"}}, diff --git a/src/pocketdb/web/SearchRpc.cpp b/src/pocketdb/web/SearchRpc.cpp index c9148606d..21df7c1b7 100644 --- a/src/pocketdb/web/SearchRpc.cpp +++ b/src/pocketdb/web/SearchRpc.cpp @@ -266,266 +266,6 @@ namespace PocketWeb::PocketWebRpc return result; } - #pragma region Recomendations OLD - // TODO (o1q): Remove below methods when the client gui switches to new methods - UniValue GetRecomendedAccountsBySubscriptions(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedaccountsbysubscriptions \"address\", count\n" - "\nAccounts recommendations by subscriptions.\n" - "\nArguments:\n" - "1. \"address\" (string) Address for recommendations\n" - "2. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - int cntOut = 10; - if (request.params.size() > 1 && request.params[1].isNum()) - cntOut = request.params[1].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsBySubscriptions(address, cntOut); - } - - UniValue GetRecomendedAccountsByScoresOnSimilarAccounts(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedaccountsbyscoresonsimilaraccounts \"address\", \"contenttypes\", height, depth, count\n" - "\nAccounts recommendations by likes based on address.\n" - "\nArguments:\n" - "1. \"address\" (string) Address for recommendations\n" - "2. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/video\n" - "3. \"height\" (int, optional) Maximum search height. Default is current chain height\n" - "4. \"depth\" (int, optional) Depth of statistic. Default 1000 blocks\n" - "5. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int nHeight = chainActive.Height(); - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); - - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByScoresOnSimilarAccounts(address, contentTypes, nHeight, depth, cntOut); - } - - UniValue GetRecomendedAccountsByScoresFromAddress(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedaccountsbyscoresfromaddress \"address\", \"contenttypes\", height, depth, count\n" - "\nAccounts recommendations by likes.\n" - "\nArguments:\n" - "1. \"address\" (string) Address for recommendations\n" - "2. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/video\n" - "3. \"height\" (int, optional) Maximum search height. Default is current chain height\n" - "4. \"depth\" (int, optional) Depth of statistic. Default 1000 blocks\n" - "5. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int nHeight = chainActive.Height(); - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); - - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByScoresFromAddress(address, contentTypes, nHeight, depth, cntOut); - } - - UniValue GetRecomendedAccountsByTags(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedaccountsbytags \"tags\", count\n" - "\nAccounts recommendations by tags.\n" - "\nArguments:\n" - "1. \"tags\" (array of strings) Tags for recommendations\n" - "2. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - vector tags; - if (request.params.size() > 0) - ParseRequestTags(request.params[0], tags); - - if (tags.empty()) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("There are no tags in the input parameters.")); - - int nHeight = chainActive.Height(); - int depth = 60 * 24 * 30; // about 1 month - - int cntOut = 10; - if (request.params.size() > 1 && request.params[1].isNum()) - cntOut = request.params[1].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedAccountsByTags(tags, nHeight, depth, cntOut); - } - - UniValue GetRecomendedContentsByScoresOnSimilarContents(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedcontentsbyscoresonsimilarcontents \"contentid\", \"contenttypes\", depth, count\n" - "\nContents recommendations by other content.\n" - "\nArguments:\n" - "1. \"contentid\" (string) Content hash for recommendations\n" - "2. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/video\n" - "3. \"depth\" (int, optional) Depth of statistic. Default 1000 blocks\n" - "4. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string contentid = request.params[0].get_str(); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum()) - depth = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - cntOut = request.params[3].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedContentsByScoresOnSimilarContents(contentid, contentTypes, depth, cntOut); - } - - UniValue GetRecomendedContentsByScoresFromAddress(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecomendedcontentsbyscoresfromaddress \"address\", \"contenttypes\", height, depth, count\n" - "\nContents recommendations for address by likes.\n" - "\nArguments:\n" - "1. \"address\" (string) Address for recommendations\n" - "2. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/video\n" - "3. \"height\" (int, optional) Maximum search height. Default is current chain height\n" - "4. \"depth\" (int, optional) Depth of statistic. Default 1000 blocks\n" - "5. \"count\" (int, optional) Number of resulting records. Default 10\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string address = request.params[0].get_str(); - CTxDestination dest = DecodeDestination(address); - - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Pocketcoin address: ") + address); - - vector contentTypes; - ParseRequestContentTypes(request.params[1], contentTypes); - - int nHeight = chainActive.Height(); - int depth = 1000; - int cntOut = 10; - - if (request.params.size() > 2 && request.params[2].isNum() && request.params[2].get_int() > 0) - nHeight = request.params[2].get_int(); - - if (request.params.size() > 3 && request.params[3].isNum()) - depth = request.params[3].get_int(); - - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); - - return request.DbConnection()->SearchRepoInst->GetRecomendedContentsByScoresFromAddress(address, contentTypes, nHeight, depth, cntOut); - } - #pragma endregion - - UniValue GetRecommendedContentByContentId(const JSONRPCRequest& request) - { - if (request.fHelp) - throw runtime_error( - "getrecommendedcontentbycontentid \"contentid\", \"address\", \"contenttypes\", \"lang\", count\n" - "\nContents recommendations by contentid for address.\n" - "\nArguments:\n" - "1. \"contentid\" (string) Content Id Hash for recommendations\n" - "2. \"address\" (string, optional) Address for which recommendations\n" - "3. \"contenttypes\" (string or array of strings, optional) type(s) of content posts/videos/articles\n" - "3. \"lang\" (string, optional) Language for recommendations\n" - "4. \"count\" (int, optional) Number of resulting records. Default 15\n" - ); - - RPCTypeCheckArgument(request.params[0], UniValue::VSTR); - string contenthash = request.params[0].get_str(); - - string address = ""; - if (request.params.size() > 1 && request.params[1].isStr()) { - address = request.params[1].get_str(); - - if(!address.empty()) { - CTxDestination dest = DecodeDestination(address); - if (!IsValidDestination(dest)) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid address: ") + address); - } - } - - vector contentTypes; - if(request.params.size()>2) - ParseRequestContentTypes(request.params[2], contentTypes); - - string lang = ""; - if (request.params.size() > 3 && request.params[3].isStr()) - lang = request.params[3].get_str(); - - int cntOut = 15; - if (request.params.size() > 4 && request.params[4].isNum()) - cntOut = request.params[4].get_int(); - - auto contentsAddresses = request.DbConnection()->WebRpcRepoInst->GetContentsAddresses(vector{contenthash}); - - UniValue result(UniValue::VARR); - auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedContentByAddressSubscriptions(contentsAddresses[contenthash], address, contentTypes, lang, cntOut, chainActive.Height(), (60 * 24 * 30 * 6), 100); - if (!ids.empty()) - { - auto contents = request.DbConnection()->WebRpcRepoInst->GetContentsData(ids, address); - result.push_backV(contents); - } - - return result; - } - UniValue GetRecommendedContentByAddress(const JSONRPCRequest& request) { if (request.fHelp) diff --git a/src/pocketdb/web/SearchRpc.h b/src/pocketdb/web/SearchRpc.h index a7c637328..252c7f7d5 100644 --- a/src/pocketdb/web/SearchRpc.h +++ b/src/pocketdb/web/SearchRpc.h @@ -23,37 +23,7 @@ namespace PocketWeb::PocketWebRpc UniValue SearchLinks(const JSONRPCRequest& request); UniValue SearchContents(const JSONRPCRequest& request); - #pragma region Recomendations OLD - // TODO (o1q): Remove below methods when the client gui switches to new methods - // Accounts recommendations based on subscriptions - // Get some accounts that were followed by people who've followed this Account - // This should be run only if Account already has followers - UniValue GetRecomendedAccountsBySubscriptions(const JSONRPCRequest& request); - - // Accounts recommendations based on scores on other Account - // Get some Accounts that were scored by people who've scored this Account (not long ago - several blocks ago) - UniValue GetRecomendedAccountsByScoresOnSimilarAccounts(const JSONRPCRequest& request); - - // Accounts recommendations based on address scores - // Get some Accounts that were scored by people who've scored like address (not long ago - several blocks ago) - // Get address scores -> Get scored contents -> Get Scores to these contents -> Get scores accounts -> Get their scores -> Get their scored contents -> Get these contents Authors - UniValue GetRecomendedAccountsByScoresFromAddress(const JSONRPCRequest& request); - - // Accounts recommendations based on tags - UniValue GetRecomendedAccountsByTags(const JSONRPCRequest& request); - - // Contents recommendations by others contents - // Get some contents that were liked by people who've seen this content (not long ago - several blocks ago) - // This should be run only if Content already has >XXXX likes - UniValue GetRecomendedContentsByScoresOnSimilarContents(const JSONRPCRequest& request); - - // Contents recommendations by address scores - // Get some contents that were liked by people who've scored like address (not long ago - several blocks ago) - UniValue GetRecomendedContentsByScoresFromAddress(const JSONRPCRequest& request); - #pragma endregion - #pragma region Recomendations - UniValue GetRecommendedContentByContentId(const JSONRPCRequest& request); UniValue GetRecommendedContentByAddress(const JSONRPCRequest& request); UniValue GetRecommendedAccountByAddress(const JSONRPCRequest& request); #pragma endregion From c8267b61daf996ebdc4f63bab911c1b1a4c53532 Mon Sep 17 00:00:00 2001 From: Andy Oknen Date: Fri, 15 Apr 2022 11:57:06 +0300 Subject: [PATCH 07/12] Extend fork time for moderation flags --- src/pocketdb/consensus/Reputation.h | 4 ++-- src/pocketdb/consensus/moderation/Flag.hpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pocketdb/consensus/Reputation.h b/src/pocketdb/consensus/Reputation.h index 0ede93c6e..31e6bb3df 100644 --- a/src/pocketdb/consensus/Reputation.h +++ b/src/pocketdb/consensus/Reputation.h @@ -282,8 +282,8 @@ namespace PocketConsensus { 1180000, 0, [](int height) { return make_shared(height); }}, { 1324655, 65000, [](int height) { return make_shared(height); }}, { 1324655, 75000, [](int height) { return make_shared(height); }}, - { 1680000, 761000, [](int height) { return make_shared(height); }}, - { 1680000, 772000, [](int height) { return make_shared(height); }}, + { 1700000, 761000, [](int height) { return make_shared(height); }}, + { 1700000, 772000, [](int height) { return make_shared(height); }}, }; public: shared_ptr Instance(int height) diff --git a/src/pocketdb/consensus/moderation/Flag.hpp b/src/pocketdb/consensus/moderation/Flag.hpp index 43bbb12be..a36a1f5c0 100644 --- a/src/pocketdb/consensus/moderation/Flag.hpp +++ b/src/pocketdb/consensus/moderation/Flag.hpp @@ -137,7 +137,7 @@ namespace PocketConsensus private: const vector> m_rules = { { 0, -1, [](int height) { return make_shared(height); }}, - { 1680000, 761000, [](int height) { return make_shared(height); }}, + { 1700000, 761000, [](int height) { return make_shared(height); }}, }; public: shared_ptr Instance(int height) From 45967abef69af24ebaa5741843fbd7b75e5104f5 Mon Sep 17 00:00:00 2001 From: Andy Oknen Date: Fri, 15 Apr 2022 12:31:52 +0300 Subject: [PATCH 08/12] Enable WebPostProcessorInst by default --- src/init.cpp | 7 ++++--- src/validation.cpp | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index fe4a28af7..93f87cdda 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -636,8 +636,8 @@ void SetupServerArgs() gArgs.AddArg("-sqltimeout", strprintf("Timeout for ReadOnly sql querys (default: %ds)", 10), false, OptionsCategory::SQLITE); gArgs.AddArg("-sqlsharedcache", strprintf("Experimental: enable shared cache for sqlite connections (default: disabled)"), false, OptionsCategory::SQLITE); gArgs.AddArg("-sqlcachesize", strprintf("Experimental: Cache size for SQLite connection in megabytes (default: %d mb)", 5), false, OptionsCategory::SQLITE); - - + gArgs.AddArg("-withoutweb", strprintf("Disable WEB part of database (default: %u)", false), false, OptionsCategory::SQLITE); + #if HAVE_DECL_DAEMON gArgs.AddArg("-daemon", "Run in the background as a daemon and accept commands", false, OptionsCategory::OPTIONS); #else @@ -1691,7 +1691,8 @@ bool AppInitMain() PocketWeb::PocketFrontendInst.Init(); - if (gArgs.GetBoolArg("-api", true)) + // Always start WEB DB building thread + if (!gArgs.GetBoolArg("-withoutweb", false)) PocketServices::WebPostProcessorInst.Start(threadGroup); // ********************************************************* Step 4b: Additional settings diff --git a/src/validation.cpp b/src/validation.cpp index 4ad105645..668f36658 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2586,7 +2586,7 @@ bool CChainState::ConnectBlock(const CBlock& block, const PocketBlockRef& pocket // ----------------------------------------------------------------------------------------------------------------- // Extend WEB database - if (gArgs.GetBoolArg("-api", true) && enablePocketConnect) + if (!gArgs.GetBoolArg("-withoutweb", false) && enablePocketConnect) PocketServices::WebPostProcessorInst.Enqueue(block.GetHash().GetHex()); // ----------------------------------------------------------------------------------------------------------------- From 9cea1c58ce599de05c2fa41b2c3f6dbe4ef26df3 Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 16:30:51 +0300 Subject: [PATCH 09/12] Changed getrecommendedcontentbyaddress --- .../repositories/web/SearchRepository.cpp | 150 +++++++++++++++++- .../repositories/web/SearchRepository.h | 4 +- src/pocketdb/web/SearchRpc.cpp | 12 +- 3 files changed, 160 insertions(+), 6 deletions(-) diff --git a/src/pocketdb/repositories/web/SearchRepository.cpp b/src/pocketdb/repositories/web/SearchRepository.cpp index 1d61d53a5..8c0ea2352 100644 --- a/src/pocketdb/repositories/web/SearchRepository.cpp +++ b/src/pocketdb/repositories/web/SearchRepository.cpp @@ -249,7 +249,7 @@ namespace PocketDb if (!lang.empty()) langFilter = "cross join Payload lang on lang.TxHash = u.Hash and lang.String1 = ?"; - int minReputation = 30; + int minReputation = 300; string sql = R"sql( select Contents.String1 @@ -320,7 +320,8 @@ namespace PocketDb return ids; } - vector SearchRepository::GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) + //TODO (o1q): remove it + vector SearchRepository::GetRecommendedContentByAddressSubscriptionsOld(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) { auto func = __func__; vector ids; @@ -338,7 +339,7 @@ namespace PocketDb if (!lang.empty()) langFilter = "cross join Payload lang on lang.TxHash = Contents.Hash and lang.String1 = ?"; - int minReputation = 30; + int minReputation = 300; string sql = R"sql( select recomendations.Id @@ -357,7 +358,7 @@ namespace PocketDb )sql" + langFilter + R"sql( where Rates.Type in (300) and Rates.Int1 = 5 - and Rates.Height > ?--0 + and Rates.Height > ? and Rates.Last in (0, 1) and Rates.String1 in ( select subscribers.String2 @@ -421,6 +422,147 @@ namespace PocketDb return ids; } + vector SearchRepository::GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth) + { + auto func = __func__; + vector ids; + + if (contentAddress.empty()) + return ids; + + string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + + string excludeAddressFilter = "?"; + if (!address.empty()) + excludeAddressFilter += ", ?"; + + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang indexed by Payload_String1_TxHash on lang.TxHash = Contents.Hash and lang.String1 = ?"; + + int minReputation = 300; + int limitSubscriptions = 50; + int limitSubscriptionsTotal = 30; + int cntRates = 1; + + string sql = R"sql( + select recomendations.Id + from ( + select Contents.String1, + Contents.Id, + Rates.String2, + count(*) count + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( )sql" + excludeAddressFilter + R"sql( ) + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in + ( + select address + from ( + select rnk, address + from ( + select 1 as rnk, subscribes.String2 as address + from Transactions subscribes indexed by Transactions_String1_Last_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribes.String2 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribes.Type in (302, 303) + and subscribes.Last = 1 + and subscribes.String1 = ? + and subscribes.Height is not null + order by subscribes.Height desc + limit ? + ) + union + select rnk, address + from ( + select 2 as rnk, subscribers.String1 as address + from Transactions subscribers indexed by Transactions_Type_Last_String2_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribers.String1 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribers.Type in (302, 303) + and subscribers.Last = 1 + and subscribers.String2 = ? + and subscribers.Height is not null + order by random() + limit ? + )) + order by rnk + limit ? + ) + group by Rates.String2 + having count(*) > ? + order by count(*) desc + ) recomendations + group by recomendations.String1 + limit ? + )sql"; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + for (const auto& contenttype: contentTypes) + TryBindStatementInt(stmt, i++, contenttype); + + TryBindStatementText(stmt, i++, contentAddress); + if (!address.empty()) + TryBindStatementText(stmt, i++, address); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + + TryBindStatementInt(stmt, i++, nHeight-depth); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, contentAddress); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, contentAddress); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, limitSubscriptionsTotal); + + TryBindStatementInt(stmt, i++, cntRates); + + TryBindStatementInt(stmt, i++, cntOut); + + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + if (auto[ok, value] = TryGetColumnInt64(*stmt, 0); ok) + ids.push_back(value); + } + + FinalizeSqlStatement(*stmt); + }); + + return ids; + } + vector SearchRepository::GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut) { auto func = __func__; diff --git a/src/pocketdb/repositories/web/SearchRepository.h b/src/pocketdb/repositories/web/SearchRepository.h index 5b32cf396..428e77acd 100644 --- a/src/pocketdb/repositories/web/SearchRepository.h +++ b/src/pocketdb/repositories/web/SearchRepository.h @@ -35,7 +35,9 @@ namespace PocketDb vector SearchUsers(const string& keyword); vector GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); - vector GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); + //TODO (o1q): remove it + vector GetRecommendedContentByAddressSubscriptionsOld(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); + vector GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */); vector GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut); }; diff --git a/src/pocketdb/web/SearchRpc.cpp b/src/pocketdb/web/SearchRpc.cpp index 21df7c1b7..133e5afaf 100644 --- a/src/pocketdb/web/SearchRpc.cpp +++ b/src/pocketdb/web/SearchRpc.cpp @@ -315,8 +315,18 @@ namespace PocketWeb::PocketWebRpc if (request.params.size() > 4 && request.params[4].isNum()) cntOut = request.params[4].get_int(); + int nHeight = chainActive.Height(); + if (request.params.size() > 5 && request.params[5].isNum() && request.params[5].get_int() > 0) + nHeight = request.params[5].get_int(); + + int depth = (60 * 24 * 30 * 3); //about 3 month as default + if (request.params.size() > 6 && request.params[6].isNum()) + { + depth = std::max(request.params[6].get_int(), (60 * 24 * 30 * 6)); // not greater than about 6 month + } + UniValue resultContent(UniValue::VARR); - auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedContentByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, chainActive.Height(), (60 * 24 * 30 * 3), 20); + auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedContentByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, nHeight, depth); if (!ids.empty()) { auto contents = request.DbConnection()->WebRpcRepoInst->GetContentsData(ids, ""); From e59bb541f358b0186272fc16db66274526840852 Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 17:29:50 +0300 Subject: [PATCH 10/12] Changed getrecommendedaccountbyaddress --- .../repositories/web/SearchRepository.cpp | 142 +++++++++++++++++- .../repositories/web/SearchRepository.h | 4 +- src/pocketdb/web/SearchRpc.cpp | 12 +- 3 files changed, 155 insertions(+), 3 deletions(-) diff --git a/src/pocketdb/repositories/web/SearchRepository.cpp b/src/pocketdb/repositories/web/SearchRepository.cpp index 8c0ea2352..0a1ce4444 100644 --- a/src/pocketdb/repositories/web/SearchRepository.cpp +++ b/src/pocketdb/repositories/web/SearchRepository.cpp @@ -231,7 +231,8 @@ namespace PocketDb return result; } - vector SearchRepository::GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) + //TODO (o1q): remove it + vector SearchRepository::GetRecommendedAccountByAddressSubscriptionsOld(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth, int cntSubscriptions) { auto func = __func__; vector ids; @@ -422,6 +423,145 @@ namespace PocketDb return ids; } + vector SearchRepository::GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth) + { + auto func = __func__; + vector ids; + + if (address.empty()) + return ids; + + string contentTypesFilter = join(vector(contentTypes.size(), "?"), ","); + + string excludeAddressFilter = "?"; + if (!addressExclude.empty()) + excludeAddressFilter += ", ?"; + + string langFilter = ""; + if (!lang.empty()) + langFilter = "cross join Payload lang on lang.TxHash = u.Hash and lang.String1 = ?"; + + int minReputation = 300; + int limitSubscriptions = 30; + int limitSubscriptionsTotal = 30; + int cntRates = 1; + + string sql = R"sql( + select Contents.String1 + from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id + cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height + on Contents.String2 = Rates.String2 + and Contents.Last = 1 + and Contents.Height > 0 + and Contents.Type in ( )sql" + contentTypesFilter + R"sql( ) + and Contents.String1 not in ( )sql" + excludeAddressFilter + R"sql( ) + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.String1 = Contents.String1 + and u.Type in (100) + and u.Last = 1 + and u.Height > 0 + )sql" + langFilter + R"sql( + where Rates.Type in (300) + and Rates.Int1 = 5 + and Rates.Height > ? + and Rates.Last in (0, 1) + and Rates.String1 in + ( + select address + from ( + select rnk, address + from ( + select 1 as rnk, subscribes.String2 as address + from Transactions subscribes indexed by Transactions_String1_Last_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribes.String2 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribes.Type in (302, 303) + and subscribes.Last = 1 + and subscribes.String1 = ? + and subscribes.Height is not null + order by subscribes.Height desc + limit ? + ) + union + select rnk, address + from ( + select 2 as rnk, subscribers.String1 as address + from Transactions subscribers indexed by Transactions_Type_Last_String2_Height + cross join Transactions u indexed by Transactions_Type_Last_String1_Height_Id + on u.Type in (100) + and u.Last = 1 and u.Height > 0 + and u.String1 = subscribers.String1 + cross join Ratings r indexed by Ratings_Type_Id_Last_Value + on r.Id = u.Id + and r.Type = 0 + and r.Last = 1 + and r.Value > ? + where subscribers.Type in (302, 303) + and subscribers.Last = 1 + and subscribers.String2 = ? + and subscribers.Height is not null + order by random() + limit ? + )) + order by rnk + limit ? + ) + group by Contents.String1 + having count(*) > ? + order by count (*) desc + limit ? + )sql"; + + TryTransactionStep(__func__, [&]() + { + auto stmt = SetupSqlStatement(sql); + + int i = 1; + for (const auto& contenttype: contentTypes) + TryBindStatementInt(stmt, i++, contenttype); + + TryBindStatementText(stmt, i++, address); + if (!addressExclude.empty()) + TryBindStatementText(stmt, i++, addressExclude); + + if (!lang.empty()) + TryBindStatementText(stmt, i++, lang); + + TryBindStatementInt(stmt, i++, nHeight-depth); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, address); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, minReputation); + TryBindStatementText(stmt, i++, address); + TryBindStatementInt(stmt, i++, limitSubscriptions); + + TryBindStatementInt(stmt, i++, limitSubscriptionsTotal); + + TryBindStatementInt(stmt, i++, cntRates); + + TryBindStatementInt(stmt, i++, cntOut); + + while (sqlite3_step(*stmt) == SQLITE_ROW) + { + if (auto[ok, value] = TryGetColumnString(*stmt, 0); ok) + ids.push_back(value); + } + + FinalizeSqlStatement(*stmt); + }); + + return ids; + } + vector SearchRepository::GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth) { auto func = __func__; diff --git a/src/pocketdb/repositories/web/SearchRepository.h b/src/pocketdb/repositories/web/SearchRepository.h index 428e77acd..18ccf9083 100644 --- a/src/pocketdb/repositories/web/SearchRepository.h +++ b/src/pocketdb/repositories/web/SearchRepository.h @@ -34,9 +34,11 @@ namespace PocketDb vector SearchUsersOld(const SearchRequest& request); vector SearchUsers(const string& keyword); - vector GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); //TODO (o1q): remove it + vector GetRecommendedAccountByAddressSubscriptionsOld(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); vector GetRecommendedContentByAddressSubscriptionsOld(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */, int cntSubscriptions = 100); + + vector GetRecommendedAccountByAddressSubscriptions(const string& address, string& addressExclude, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */); vector GetRecommendedContentByAddressSubscriptions(const string& contentAddress, string& address, const vector& contentTypes, const string& lang, int cntOut, int nHeight, int depth = 129600 /* about 3 month */); vector GetRandomContentByAddress(const string& contentAddress, const vector& contentTypes, const string& lang, int cntOut); }; diff --git a/src/pocketdb/web/SearchRpc.cpp b/src/pocketdb/web/SearchRpc.cpp index 133e5afaf..03f88358f 100644 --- a/src/pocketdb/web/SearchRpc.cpp +++ b/src/pocketdb/web/SearchRpc.cpp @@ -394,8 +394,18 @@ namespace PocketWeb::PocketWebRpc if (request.params.size() > 4 && request.params[4].isNum()) cntOut = request.params[4].get_int(); + int nHeight = chainActive.Height(); + if (request.params.size() > 5 && request.params[5].isNum() && request.params[5].get_int() > 0) + nHeight = request.params[5].get_int(); + + int depth = (60 * 24 * 30 * 3); //about 3 month as default + if (request.params.size() > 6 && request.params[6].isNum()) + { + depth = std::max(request.params[6].get_int(), (60 * 24 * 30 * 6)); // not greater than about 6 month + } + UniValue result(UniValue::VARR); - auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedAccountByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, chainActive.Height(), (60 * 24 * 30 * 3), 10); + auto ids = request.DbConnection()->SearchRepoInst->GetRecommendedAccountByAddressSubscriptions(address, addressExclude, contentTypes, lang, cntOut, nHeight, depth); if (!ids.empty()) { auto profiles = request.DbConnection()->WebRpcRepoInst->GetAccountProfiles(ids, true); From 0974452148183b8d1b3b25a1831517d95f768ba2 Mon Sep 17 00:00:00 2001 From: only1question Date: Fri, 15 Apr 2022 18:30:16 +0300 Subject: [PATCH 11/12] remove not existing methods from RPCCache --- src/rpc/cache.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/rpc/cache.h b/src/rpc/cache.h index c6de8772c..88bda9a37 100644 --- a/src/rpc/cache.h +++ b/src/rpc/cache.h @@ -58,9 +58,6 @@ class RPCCache "getstatisticbydays", "getstatisticcontentbyhours", "getstatisticcontentbydays", - "getrecomendedaccountsbytags", - "getrecomendedcontentsbyscoresonsimilarcontents", - "getrecommendedcontentbycontentid", "getrecommendedcontentbyaddress", "getrecommendedaccountbyaddress", "getaddressinfo", From c9b32ae89664bbe2b4ddd8ae002f5d1c4f432f34 Mon Sep 17 00:00:00 2001 From: only1question Date: Sat, 16 Apr 2022 13:22:57 +0300 Subject: [PATCH 12/12] Improved quality GetRecommendedContentByAddressSubscriptions --- src/pocketdb/repositories/web/SearchRepository.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pocketdb/repositories/web/SearchRepository.cpp b/src/pocketdb/repositories/web/SearchRepository.cpp index 0a1ce4444..c447ce988 100644 --- a/src/pocketdb/repositories/web/SearchRepository.cpp +++ b/src/pocketdb/repositories/web/SearchRepository.cpp @@ -590,7 +590,7 @@ namespace PocketDb from ( select Contents.String1, Contents.Id, - Rates.String2, + --Rates.String2, count(*) count from Transactions Rates indexed by Transactions_Type_Last_String1_Height_Id cross join Transactions Contents indexed by Transactions_Type_Last_String2_Height @@ -652,11 +652,13 @@ namespace PocketDb order by rnk limit ? ) - group by Rates.String2 + --group by Rates.String2 + group by Contents.Id having count(*) > ? order by count(*) desc ) recomendations group by recomendations.String1 + order by recomendations.count desc limit ? )sql";