예제 #1
0
        /// <summary>
        /// Returns the information on each word with ids in resultIDs.
        /// </summary>
        /// <param name="explore"></param>
        /// <param name="resultIDs"></param>
        /// <returns></returns>
        private static List <WordwDefinition> GetWordInformation(ExploreVM explore, IEnumerable <int> resultIDs)
        {
            Sql definitionsSql = new Sql(@"SELECT Words.ID, Words.Word, Words.Popularity, DefinitionID, Definition, Definitions.LanguageID AS LanguageID, NULL As Relationship, NULL AS BaseWord, Rank FROM Definitions
                    INNER JOIN Word_Definition ON Definitions.ID = Word_Definition.DefinitionID
                    INNER JOIN Words ON Word_Definition.WordID = Words.ID
                    WHERE Words.ID IN (@0)", resultIDs);

            Sql allRelatedSql = new Sql(@"SELECT Words.ID, Words.Word, Words.Popularity, NULL AS DefinitionID, NULL AS Definition, NULL AS LanguageID, Relationship, BaseWords.Word AS BaseWord, RelationshipID + 20 AS Rank 
                    FROM WordRelationships
                    INNER JOIN Words ON WordRelationships.WordB = Words.ID
                    INNER JOIN Relationships ON WordRelationships.RelationshipID = Relationships.ID
                    INNER JOIN Words AS BaseWords ON WordRelationships.WordA = BaseWords.ID
                    WHERE Words.ID IN (@0)", resultIDs);

            Sql compactInfoSql = new Sql(@"SELECT Words.ID, Words.Word, Words.Popularity, NULL AS DefinitionID, NULL AS Definition, NULL AS LanguageID, Relationship, BaseWords.Word AS BaseWord, RelationshipID + 20 AS Rank 
                    FROM WordRelationships
                    INNER JOIN Words ON WordRelationships.WordA = Words.ID
                    INNER JOIN Relationships ON WordRelationships.RelationshipID = Relationships.ID
                    INNER JOIN Words AS BaseWords ON WordRelationships.WordB = BaseWords.ID
                    WHERE Words.ID IN (@0)", resultIDs);

            //Sql compactInfoSql = new Sql(@"SELECT Words.ID, Words.Word, Words.Popularity, NULL AS DefinitionID, NULL AS Definition, NULL AS LanguageID, Relationship, BaseWords.Word AS BaseWord, RelationshipID + 20 AS Rank
            //        FROM WordRelationships
            //        INNER JOIN Words ON WordRelationships.WordB = Words.ID
            //        INNER JOIN Relationships ON WordRelationships.RelationshipID = Relationships.ID
            //        INNER JOIN Words AS BaseWords ON WordRelationships.WordA = BaseWords.ID
            //        WHERE Words.ID IN (@0)", resultIDs);

            Sql infoSql;

            // if there is only one result, return all of the information available: itself and related entries.
            if (resultIDs.ToArray().Length == 1)
            {
                infoSql = definitionsSql.Append("UNION").Append(allRelatedSql);
            }
            // otherwise just return where it, itself, has an entry.
            else
            {
                infoSql = definitionsSql.Append("UNION").Append(compactInfoSql);
            }

            Sql orderBy = new Sql("ORDER BY LanguageID, Rank, DefinitionID");

            infoSql.Append(orderBy);

            List <WordwDefinition> results = db.Fetch <WordwDefinition>(infoSql);

            if (results.Count == 0)
            {
                results = db.Fetch <WordwDefinition>(compactInfoSql.Append(orderBy));
            }

            return(results);
        }
예제 #2
0
        private static List <string> GetConcepts(ExploreVM explore)
        {
            PropertyInfo[] properties = typeof(ExploreVM).GetProperties();
            List <string>  concepts   = new List <string>();

            foreach (PropertyInfo property in properties)
            {
                bool isPropBool = property.PropertyType == Type.GetType("System.Boolean");

                if (!isPropBool)
                {
                    continue;
                }
                if (property.Name.StartsWith("is"))
                {
                    continue;
                }

                bool isChecked = (bool)property.GetValue(explore);
                if (isChecked)
                {
                    concepts.Add(property.Name);
                }
            }

            for (int i = 0; i < concepts.Count; i++)
            {
                string concept = concepts[i];
                if (!concept.Contains("_"))
                {
                    continue;
                }

                string[] elems = concept.Split('_');
                concept = elems[1] + "-" + elems[0];
                if (elems.Length > 2)
                {
                    concept += "-long";
                }
                concepts[i] = concept;
            }

            return(concepts);
        }
예제 #3
0
        public static List <FullWord> GetWordsByExplore(ExploreVM explore)
        {
            IEnumerable <int> resultIDs = GetWordsToReturn(explore);

            List <WordwDefinition> resultWords = GetWordInformation(explore, resultIDs);

            Dictionary <string, FullWord> resultDict = new Dictionary <string, FullWord>();

            foreach (WordwDefinition entry in resultWords)
            {
                FullWord fw;

                // "Search Distance" is a measure of the difference between the search term and the returned term.
                // However, if the search is of definitions, the "Search Distance" is instead the
                // index of the first appearance of the search term in a definition.


                if (resultDict.ContainsKey(entry._Word))
                {
                    fw = resultDict[entry._Word];
                }
                else
                {
                    fw             = new FullWord();
                    fw._Word       = entry._Word;
                    fw.ID          = entry.ID;
                    fw.Definitions = new List <Definition>();
                    fw.Popularity  = entry.Popularity;
                    fw.Related     = new List <RelatedWord>();
                    if (explore.isDefinitionSearch)
                    {
                        fw.SearchDistance = int.MaxValue;                             // this is measured later.
                    }
                    else
                    {
                        fw.SearchDistance = LevenshteinDistance.Compute(fw._Word, explore.search);
                    }
                    resultDict[entry._Word] = fw;
                }

                var isDef = entry.Definition != null;

                if (isDef)
                {
                    Definition def = new Definition()
                    {
                        _Definition = entry.Definition, LanguageID = entry.LanguageID
                    };
                    fw.Definitions.Add(def);

                    if (explore.isDefinitionSearch)
                    {
                        // compute search distance
                        int defSearchDistance = -1;
                        if (!String.IsNullOrEmpty(explore.search))
                        {
                            def._Definition.IndexOf(explore.search);
                        }
                        if (defSearchDistance == -1)
                        {
                            defSearchDistance = int.MaxValue;
                        }
                        fw.SearchDistance = Math.Min(fw.SearchDistance, defSearchDistance);
                    }
                }
                else
                {
                    RelatedWord rel = new RelatedWord()
                    {
                        ID = entry.BaseWordID ?? default(int), Relationship = entry.Relationship, Word = entry.BaseWord
                    };
                    fw.Related.Add(rel);
                }
            }

            if (resultDict.Count > 0)
            {
                return(resultDict.Values.OrderBy(e => e.SearchDistance).ToList <FullWord>());
            }
            else
            {
                return(new List <FullWord>()); // empty list.
            }
        }
예제 #4
0
        public static List <FullWord> GetWordsByExploreOLD(ExploreVM explore)
        {
            PropertyInfo[] properties = typeof(ExploreVM).GetProperties();
            List <string>  concepts   = new List <string>();

            foreach (PropertyInfo property in properties)
            {
                bool isPropBool = property.PropertyType == Type.GetType("System.Boolean");

                if (!isPropBool)
                {
                    continue;
                }
                if (property.Name.StartsWith("is"))
                {
                    continue;
                }

                bool isChecked = (bool)property.GetValue(explore);
                if (isChecked)
                {
                    concepts.Add(property.Name);
                }
            }

            for (int i = 0; i < concepts.Count; i++)
            {
                string concept = concepts[i];
                if (!concept.Contains("_"))
                {
                    continue;
                }

                string[] elems = concept.Split('_');
                concept = elems[1] + "-" + elems[0];
                if (elems.Length > 2)
                {
                    concept += "-long";
                }
                concepts[i] = concept;
            }


            bool hasSearchTerm = !string.IsNullOrWhiteSpace(explore.search);
            Sql  sql           = new Sql(@"SELECT Words.ID, Words.Word, Words.Popularity, Definition");


            if (explore.isDefinitionSearch)
            {
                sql.Append(@"FROM Definitions
                            INNER JOIN Word_Definition ON Definitions.ID = Word_Definition.DefinitionID
                            INNER JOIN Words ON Word_Definition.WordID = Words.ID");
            }
            else
            {
                sql.Append(@", Relationship, BaseWords.Word as BaseWord FROM Words
                            LEFT OUTER JOIN Word_Definition ON Words.ID = Word_Definition.WordID
                            LEFT OUTER JOIN Definitions ON Word_Definition.DefinitionID = Definitions.ID
                            LEFT OUTER JOIN WordRelationships ON Words.ID = WordRelationships.WordA
                            LEFT OUTER JOIN Relationships ON WordRelationships.RelationshipID = Relationships.ID
                            LEFT OUTER JOIN Words AS BaseWords ON WordRelationships.WordB = BaseWords.ID");
            }


            if (hasSearchTerm)
            {
                if (explore.originalSearch == null)
                {
                    explore.originalSearch = explore.search.Replace("*", "");
                }
                string searchTerm = explore.search.Replace('*', '%');


                if (explore.isDefinitionSearch)
                {
                    if (!searchTerm.Contains('%'))
                    {
                        searchTerm = string.Format("%{0}%", searchTerm);
                    }
                    sql.Append(@"WHERE Definition LIKE (@0)", searchTerm);
                }
                else
                {
                    searchTerm = searchTerm.Replace("a:", "ä").Replace("o:", "ö"); // perhaps this should be on the client side
                    searchTerm = searchTerm.Trim().ToLower();

                    sql.Append(@"WHERE Words.Word LIKE (@0)", searchTerm);
                }
            }

            // sql.Append(@"");

            if (concepts.Count > 0)
            {
                if (hasSearchTerm)
                {
                    sql.Append("AND");
                }
                else
                {
                    sql.Append("WHERE");
                }
                sql.Append(@"Words.ID IN (
                                SELECT Words.ID FROM Words
                                INNER JOIN Word_Concept ON Words.ID = Word_Concept.WordID
                                INNER JOIN Concepts ON Word_Concept.ConceptID = Concepts.ID
                                WHERE Concept IN (@0) AND Popularity IS NOT NULL
                                GROUP BY Words.ID
                                HAVING COUNT(*) = @1)", concepts.ToArray(), concepts.Count);
            }

            if (explore.isDefinitionSearch)
            {
                sql.Append("ORDER BY Words.Popularity DESC, Words.Word");
            }
            else
            {
                sql.Append("ORDER BY Words.Popularity DESC, Words.ID, RelationshipID");
            }

            Debug.WriteLine(sql);
            List <WordwDefinition> wordsDefs = db.Fetch <WordwDefinition>(sql);
            List <FullWord>        resultSet = new List <FullWord>();
            List <string>          relList   = new List <string>();

            // TODO: There is a way to do this with LINQ but, for now....

            int             wordID = 0;
            FullWord        word   = null;
            WordwDefinition wDef   = null;

            for (int i = 0; i < wordsDefs.Count; i++)
            {
                wDef = wordsDefs[i];
                bool isNew = wordID != wDef.ID;
                if (isNew)
                {
                    if (word != null && relList.Count > 0)
                    { // finish up the previous word
                      // adding definitions derived from relationships at the end of the list of definitions.
                        if (word.Definitions == null)
                        {
                            word.Definitions = new List <Definition>();
                        }
                        for (int j = 0; j < relList.Count; j++)
                        {
                            Definition def = new Definition()
                            {
                                _Definition = relList[j]
                            };
                            word.Definitions.Add(def);
                        }
                    }


                    word    = new FullWord();
                    relList = new List <string>();

                    word.ID         = wDef.ID;
                    word._Word      = wDef._Word;
                    word.Popularity = wDef.Popularity;
                    resultSet.Add(word);
                    wordID = wDef.ID;

                    word.SearchDistance = LevenshteinDistance.Compute(word._Word, explore.originalSearch);
                }

                if (!string.IsNullOrEmpty(wDef.Definition))
                {
                    if (word.Definitions == null)
                    {
                        word.Definitions = new List <Definition>();
                    }
                    bool hasDef = word.Definitions.Any <Definition>(t => t._Definition == wDef.Definition);
                    if (!hasDef)
                    {
                        Definition def = new Definition()
                        {
                            _Definition = wDef.Definition
                        };
                        if (!word.Definitions.Contains(def))
                        {
                            word.Definitions.Add(def);
                        }
                    }
                }

                if (!string.IsNullOrEmpty(wDef.Relationship))
                {
                    string relDefStr = String.Format("{0}: <a href={1}>{1}</a>", wDef.Relationship, wDef.BaseWord);
                    if (!relList.Contains(relDefStr))
                    {
                        relList.Add(relDefStr);
                    }
                }
            }



            if (resultSet.Count == 1)
            {
                Sql relatedSql = new Sql(@"SELECT RelatedWords.Word, Relationship FROM WordRelationships
                    INNER JOIN Words AS RelatedWords ON WordRelationships.WordA = RelatedWords.ID
                    INNER JOIN Words ON WordRelationships.WordB = Words.ID
                    INNER JOIN Relationships ON WordRelationships.RelationshipID = Relationships.ID
                    WHERE Words.Word = @0
                    ORDER BY RelationshipID", explore.search);

                List <WordwDefinition> relWordList = db.Fetch <WordwDefinition>(relatedSql);

                if (relWordList.Count > 0)
                {
                    relList = new List <string>();
                }

                for (int k = 0; k < relWordList.Count; k++)
                {
                    WordwDefinition relW = relWordList[k];
                    if (!string.IsNullOrEmpty(relW.Relationship))
                    {
                        string relDefStr = String.Format("{0}: <a href={1}>{1}</a>", relW.Relationship, relW._Word);
                        if (!relList.Contains(relDefStr))
                        {
                            relList.Add(relDefStr);
                        }
                    }
                }
            }

            if (word != null && wDef != null && relList.Count > 0)
            { // finish up the previous word
              // adding definitions derived from relationships at the end of the list of definitions.
                if (word.Definitions == null)
                {
                    word.Definitions = new List <Definition>();
                }
                for (int j = 0; j < relList.Count; j++)
                {
                    Definition def = new Definition()
                    {
                        _Definition = relList[j]
                    };
                    word.Definitions.Add(def);
                }
            }


            if (resultSet.Count == 0 && explore.search.Length > 1)
            {
                string broaderTerm    = explore.search;
                bool   hasEndWildcard = (broaderTerm[broaderTerm.Length - 1] == '*');

                if (hasEndWildcard)
                {
                    broaderTerm = broaderTerm.Substring(0, broaderTerm.Length - 2);
                }


                broaderTerm   += '*';
                explore.search = broaderTerm;

                resultSet = GetWordsByExplore(explore);
            }



            if (!explore.isDefinitionSearch && hasSearchTerm && resultSet.Count > 0 && resultSet.First().SearchDistance > 0)
            {
                resultSet.Sort((a, b) => a.SearchDistance.CompareTo(b.SearchDistance));
            }

            return(resultSet);
        }
예제 #5
0
        /// <summary>
        /// Returns the ids of the words wanted.
        /// </summary>
        /// <param name="explore"></param>
        /// <returns></returns>
        private static IEnumerable <int> GetWordsToReturn(ExploreVM explore)
        { // This just returns a set of ids.
            IEnumerable <int> resIDs;

            string searchTerm    = explore.search;
            bool   hasSearchTerm = !string.IsNullOrEmpty(searchTerm);

            if (explore.isAdmin)
            {
                explore.rowsPerPage = 500;
            }

            List <string> concepts = GetConcepts(explore);

            do
            {
                Sql sql = new Sql();

                sql.Append(@"SELECT Words.ID FROM Words");

                if (hasSearchTerm)
                {
                    string sqlSearchTerm = searchTerm.Replace('*', '%');
                    sqlSearchTerm = sqlSearchTerm.Trim().ToLower();


                    if (explore.isDefinitionSearch)
                    {
                        if (!sqlSearchTerm.Contains('%'))
                        {
                            sqlSearchTerm = string.Format("%{0}%", sqlSearchTerm);
                        }
                        sql.Append(@"INNER JOIN Word_Definition ON Words.ID = Word_Definition.WordID
                                    INNER JOIN Definitions ON Word_Definition.DefinitionID = Definitions.ID 
                                    WHERE Definition LIKE (@0)", sqlSearchTerm);
                    }
                    else
                    {
                        sql.Append(@"WHERE Words.Word LIKE (@0)", sqlSearchTerm);
                    }
                }

                if (concepts.Count > 0)
                {
                    if (hasSearchTerm)
                    {
                        sql.Append("AND");
                    }
                    else
                    {
                        sql.Append("WHERE");
                    }
                    sql.Append(@"Words.ID IN (
                                SELECT Words.ID FROM Words
                                INNER JOIN Word_Concept ON Words.ID = Word_Concept.WordID
                                INNER JOIN Concepts ON Word_Concept.ConceptID = Concepts.ID
                                WHERE Concept IN (@0) AND Popularity IS NOT NULL
                                GROUP BY Words.ID
                                HAVING COUNT(*) = @1)", concepts.ToArray(), concepts.Count);
                }

                sql.Append("ORDER BY Popularity DESC");

                int offset    = explore.pageNum * explore.rowsPerPage;
                int fetchNext = explore.rowsPerPage;

                sql.Append("OFFSET @0 ROWS", offset);
                sql.Append("FETCH NEXT @0 ROWS ONLY", fetchNext);


                resIDs = db.Fetch <int>(sql);

                if (resIDs.Any() || string.IsNullOrEmpty(searchTerm))
                {
                    continue;
                }

                bool hasEndWildcard = (searchTerm[searchTerm.Length - 1] == '*');

                if (hasEndWildcard)
                {
                    searchTerm = searchTerm.Substring(0, searchTerm.Length - 2);
                }


                searchTerm += '*';
            } while (!resIDs.Any() && searchTerm.Length > 2);

            return(resIDs);
        }