【问题标题】:Java what's the best data structure to search objects by keywords [closed]Java通过关键字搜索对象的最佳数据结构是什么[关闭]
【发布时间】:2014-06-25 17:01:28
【问题描述】:

假设我有一个“期刊文章”类,其中包含年份、作者、标题、期刊名称、关键字等变量。

作者和关键字等变量可能被声明为 String[] authorsString[] 关键字

在一组“期刊论文”对象中通过一个或多个“关键字”、几个作者姓名中的一个或标题的一部分进行搜索的最佳数据结构是什么?

谢谢!

================================================ ============================ 在大家的帮助下,通过Processing环境实现的测试代码如下所示。非常感谢您的建议!谢谢!

ArrayList<Paper> papers = new ArrayList<Paper>();

HashMap<String, ArrayList<Paper>> hm = new HashMap<String, ArrayList<Paper>>();

void setup(){
  Paper paperA = new Paper();
  paperA.title = "paperA";
  paperA.keywords.append("cat");
  paperA.keywords.append("dog");
  paperA.keywords.append("egg");
  //println(paperA.keywords);
  papers.add(paperA);

  Paper paperC = new Paper();
  paperC.title = "paperC";
  paperC.keywords.append("egg");
  paperC.keywords.append("cat");
  //println(paperC.keywords);
  papers.add(paperC);

  Paper paperB = new Paper();
  paperB.title = "paperB";
  paperB.keywords.append("dog");
  paperB.keywords.append("egg");
  //println(paperB.keywords); 
  papers.add(paperB);

  for (Paper p : papers) {
    // get a list of keywords for the current paper
    StringList keywords = p.keywords;

    // go through each keyword of the current paper
    for (int i=0; i<keywords.size(); i++) {
      String keyword = keywords.get(i);

      if ( hm.containsKey(keyword) ) { 
        // if the hashmap has this keyword
        // get the current paper list associated with this keyword
        // which is the "value" of this keyword
        ArrayList<Paper> papers = hm.get(keyword);        
        papers.add(p); // add the current paper to the paper list        
        hm.put(keyword, papers); // put the keyword and its paper list back to hashmap
      } else { 
        // if the hashmap doesn't have this keyword
        // create a new Arraylist to store the papers with this keyword
        ArrayList<Paper> papers = new ArrayList<Paper>();        
        papers.add(p); // add the current paper to this ArrayList        
        hm.put(keyword, papers); // put this new keyword and its paper list to hashmap
      }
    }

  }

  ArrayList<Paper> paperList = new ArrayList<Paper>();
  paperList = hm.get("egg");
  for (Paper p : paperList) {
    println(p.title);
  }
}

void draw(){}

class Paper 
{
  //===== variables =====
  int ID;
  int year;
  String title;
  StringList authors  = new StringList();
  StringList keywords = new StringList();
  String DOI;
  String typeOfRef;
  String nameOfSource;
  String abs; // abstract


  //===== constructor =====

  //===== update =====

  //===== display =====
}

【问题讨论】:

  • 你现在用的是什么?
  • 使用solr?

标签: java data-structures keyword-search


【解决方案1】:

使用HashMap&lt;String, JournalArticle&gt; 数据结构。

例如

Map<String, JournalArticle> journals = new HashMap<String, JournalArticle>();
journals.put("keyword1", testJA);

if (journals.containsKey("keyword1")
{
    return journals.get("keyword1");
}

你可以把你的关键字作为String类型的key放在这个map中,但是它只支持“exact-match”类型的搜索,这意味着你必须在你的搜索。

如果您正在寻找“like”类型的搜索,我建议您将对象保存在支持“like”查询的数据库中。

编辑:再想一想,我认为您可以执行某种“like”查询(就像 SQL 中的 like 子句),但效率不会太高很好,因为每当您进行查询时,您都在遍历 HashMap 中的所有键。如果您知道正则表达式,您可以通过修改以下示例代码(例如 key.matches(pattern))进行各种查询:

    List<JournalArticle> results = null;

    for (String key : journals.keySet())
    {
        if (key.contains("keyword"))  /* keyword has to be part of the key stored in the HashMap, but does not have to be an exact match any more */
            results.add(journals.get(key));
    }

    return results;

【讨论】:

  • 谢谢,托尼!如果我想获取包含某个关键字或多个关键字的所有“期刊文章”对象,而不是一对一匹配怎么办?
  • 您可以使用 Set 作为 HashMap 中的值。 Map> journals = new HashMap();
【解决方案2】:

对于简单的情况,您可以使用Multimap&lt;String, Article&gt;。 Guava 库中有一个。

对于大量数据,Apache Lucene 将更适合。

【讨论】:

    【解决方案3】:

    我会创建一个从关键字(如作者或标题等)到一组 JournalArticles 的映射。

    Map<String, Set<JournalArticle>> keyWordMap = new HashMap<>();
    Map<String, Set<JournalArticle>> authorMap = new HashMap<>();
    

    当您创建一个新的 JournalArticle 时,对于它的每个关键词,您应该将该文章添加到适当的集合中。

    JournalArticle ja = new  JournalArticle();
    for(String keyWorld : ja.getKeyWords())
    {
        if(keyWordMap.containsKey(keyWorld) == false)
            keyWordMap.put(keyWorld, new HashSet<JournalArticle>());
        keyWordMap.get(keyWorld).add(ja);
    }
    

    要进行查找,您可以执行以下操作:

    String keyWord = "....";
    Set<JournalArticle> matchingSet = keyWordMap.get(keyWord);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 2023-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多