public IEnumerable <PrcRecommendationResult> RecommendById(string id, PrcSettingsElastic prcSettings, PrcRecommendationByIdRequest request) { var result = new List <PrcRecommendationResult>(); var globalStoreDataSet = GlobalStore.DataSets.Get(prcSettings.DataSetName); var dataSet = globalStoreDataSet.DataSet; var documentQuery = queryFactory.GetDocumentQuery(dataSet.Name); var fieldsForRecommendation = prcSettings.FieldsForRecommendation; var filterOrWeight = !string.IsNullOrEmpty(request.Query) || request?.Weights?.Any() == true; var tagId = string.Empty; if (string.IsNullOrEmpty(request.TagId)) { var documentElastic = documentQuery.Get(request.DocumentId); if (documentElastic == null) { return(result); } var tagToken = JTokenHelper.GetToken(documentElastic.DocumentObject).GetPathToken(dataSet.TagField); tagId = JTokenHelper.GetUnderlyingToken(tagToken)?.ToString(); if (tagId == null) { return(result); } } else { tagId = request.TagId; } var similarDocIdsWithScore = redisHandler.GetTopNDocuments(new PrcIndexRedisKey(id, tagId, request.DocumentId), filterOrWeight ? -1 : request.Count - 1); Dictionary <string, double> resultDictionary = similarDocIdsWithScore; var documentElastics = (filterOrWeight || request.NeedDocumentInResult) ? GetDocuments(dataSet.Name, request.Query, null, fieldsForRecommendation, similarDocIdsWithScore.Keys, request.NeedDocumentInResult) : null; // ha a Filter és a Weights is üres, a TOP Count doksi Id - t visszaadjuk score-jaikkal. (ha kell a document is, akkor elastic - tól elkérjük ezeket pluszban) if (filterOrWeight) { // ezekre a doksikra módosítjuk a prc score - t a Weights-el var docIdsWithScore = documentElastics.ToDictionary(k => k.Id, v => similarDocIdsWithScore[v.Id]); //súlyozás if (request?.Weights?.Any() == true) { var weightsDic = request.Weights.ToDictionary(key => Guid.NewGuid().ToString(), value => value); var docIds = docIdsWithScore.Keys.ToList(); var queries = weightsDic.ToDictionary(key => key.Key, value => documentQuery.PrefixQueryFields(value.Value.Query, globalStoreDataSet.DocumentFields)); var ids = documentQuery.GetExistsForQueries(queries, docIds).ToDictionary(k => k.Key, v => v.Value.ToDictionary(ke => ke, va => va)); var allWeightsCount = request.Weights.Count; foreach (var docId in docIds) { var weightsSum = weightsDic.Where(w => ids[w.Key].ContainsKey(docId)).Sum(w => w.Value.Value); var pow = 1 + (weightsSum / allWeightsCount); var score = Math.Pow(docIdsWithScore[docId] + 1, pow) - 1; docIdsWithScore[docId] = score; } } resultDictionary = docIdsWithScore; } var recommendation = resultDictionary .OrderByDescending(o => o.Value) .Take(request.Count) .Select(s => new PrcRecommendationResult() { DocumentId = s.Key, Score = s.Value, Document = request.NeedDocumentInResult ? documentElastics.SingleOrDefault(d => d.Id == s.Key).DocumentObject : null }); return(recommendation); }
private void AddGlobalStoreInternal(string name, string indexName, DataSet dataSet) { var paths = new List <string>(); var attachments = new List <string>(); var tagIsArray = false; var tagIsInteger = false; if (dataSet.SampleDocument != null) { var pathTokens = DocumentHelper.GetAllPathTokens(dataSet.SampleDocument); paths = pathTokens.Keys.ToList(); if (!pathTokens.ContainsKey(dataSet.TagField)) { throw new InvalidOperationException($"DataSet Name: ´{name}´, Index: ´{indexName}´. SampleDocument does not contain TagField ´{dataSet.TagField}´"); } var tagToken = pathTokens[dataSet.TagField]; tagIsArray = tagToken.Type == JTokenType.Array; if (tagIsArray) { tagIsInteger = JTokenHelper.GetUnderlyingToken(tagToken).Type == JTokenType.Integer; } else { tagIsInteger = tagToken.Type == JTokenType.Integer; } } else if (dataSet.Schema != null) { var pathDictionary = SchemaHelper.GetPaths(dataSet.Schema); paths = pathDictionary.Keys.ToList(); attachments = pathDictionary .Where(kv => kv.Value.Item1 == SchemaHelper.Types.Attachment) .Select(kv => kv.Key) .ToList(); if (!pathDictionary.ContainsKey(dataSet.TagField)) { throw new InvalidOperationException($"DataSet Name: ´{name}´, Index: ´{indexName}´. Schema does not contain TagField ´{dataSet.TagField}´"); } var tagTuple = pathDictionary[dataSet.TagField]; tagIsArray = SchemaHelper.IsArray(tagTuple.Item1); if (tagIsArray) { tagIsInteger = SchemaHelper.IsInteger(tagTuple.Item2); } else { tagIsInteger = SchemaHelper.IsInteger(tagTuple.Item1); } } else { throw new InvalidOperationException("DataSet has no SampleDocument nor Schema property"); } GlobalStore.DataSets.Add(name ?? indexName, new GlobalStoreDataSet(name, indexName, dataSet, paths, tagIsArray, tagIsInteger, attachments)); }