lucene查询在一个字段中是模糊的,在另一个字段中是精确的

lucene查询在一个字段中是模糊的,在另一个字段中是精确的,lucene,Lucene,问题: 在lucene 4.5中,如何将一个字段中的精确匹配与另一个字段中的模糊搜索相结合 问题: 我在lucene索引中为NGA地理名称地名录编制了索引。我需要模糊查询一个字段(地名),但将查询限制为具有特定国家代码的记录。下面是我正在运行的示例查询 我没有使用SOLR,我做了大量的研究和尝试,但我没有明确的答案,可能是我太慢了 FULL_NAME_ND_RO:india AND CC1:in 我想对印度进行模糊搜索,但我只想要与“in”(国家代码)完全匹配的记录 以下是为Gaz编制索引的

问题:

在lucene 4.5中,如何将一个字段中的精确匹配与另一个字段中的模糊搜索相结合

问题:

我在lucene索引中为NGA地理名称地名录编制了索引。我需要模糊查询一个字段(地名),但将查询限制为具有特定国家代码的记录。下面是我正在运行的示例查询
我没有使用SOLR,我做了大量的研究和尝试,但我没有明确的答案,可能是我太慢了

FULL_NAME_ND_RO:india AND CC1:in 
我想对印度进行模糊搜索,但我只想要与“in”(国家代码)完全匹配的记录

以下是为Gaz编制索引的代码:

public void index(File outputIndexDir, File gazateerInputData, GazType type) throws Exception {
    if (!outputIndexDir.isDirectory()) {
      throw new IllegalArgumentException("outputIndexDir must be a directory.");
    }

    String indexloc = outputIndexDir + type.toString();
    Directory index = new MMapDirectory(new File(indexloc));

    Analyzer a = new StandardAnalyzer(Version.LUCENE_45);
    IndexWriterConfig config = new IndexWriterConfig(Version.LUCENE_45, a);

    IndexWriter w = new IndexWriter(index, config);

    readFile(gazateerInputData, w, type);
    w.commit();
    w.close();

  }

  public void readFile(File gazateerInputData, IndexWriter w, GazType type) throws Exception {
    BufferedReader reader = new BufferedReader(new FileReader(gazateerInputData));
    List<String> fields = new ArrayList<String>();
    int counter = 0;
    // int langCodeIndex = 0;
    System.out.println("reading gazateer data from file...........");
    while (reader.read() != -1) {
      String line = reader.readLine();
      String[] values = line.split(type.getSeparator());
      if (counter == 0) {
        for (String columnName : values) {
          fields.add(columnName.replace("»¿", "").trim());
        }

      } else {
        Document doc = new Document();
        for (int i = 0; i < fields.size() - 1; i++) {
          if (fields.get(i).equals("CC1")) {
            doc.add(new StringField(fields.get(i), values[i], Field.Store.YES));
          } else {
            doc.add(new TextField(fields.get(i), values[i], Field.Store.YES));
          }
        }

        w.addDocument(doc);

      }
      counter++;
      if (counter % 10000 == 0) {
        w.commit();
        System.out.println(counter + " .........committed to index..............");
      }

    }
    w.commit();
    System.out.println("Completed indexing gaz! index name is: " + type.toString());
  }
geonamesAnalyzer是一个StandardAnalyzer…luceneQueryString与上面的查询类似


任何建议都很好。

最简单的答案似乎只是运行一个模糊查询,例如:

但是,如果需要对每个字段进行不同的分析,可以使用


根据以下评论:

StandardAnalyzer中设置的默认stopword包含单词“in”,因此搜索词将从查询中完全删除。可以通过以下方式覆盖停止字集:

由于CC1字段是一个StringField(因此,在索引时未对其进行分析),因此确保在查询时也未对其进行分析可能是有意义的。尽管上述方法解决了stopword问题,但您可能仍会遇到与大小写相关或标记化的问题。通常适用于未分析的字段。可以向查询解析器传递一个分析规则,以将不同的分析规则应用于不同的字段

比如:

Map<String,Analyzer> analyzerPerField = new HashMap<String,Analyzer>();
analyzerPerField.put("CC1", new KeywordAnalyzer());

PerFieldAnalyzerWrapper aWrapper =
  new PerFieldAnalyzerWrapper(geonamesAnalyzer, analyzerPerField);

QueryParser parser = new QueryParser(Version.LUCENE_45, defaultField, aWrapper);
Map analyzerPerField=new HashMap();
analyzerPerField.put(“CC1”,新关键字Analyzer());
PerfielDanalyzerRapper aWrapper=
新型PerfielDanalyzerRapper(地理名称分析器,analyzerPerField);
QueryParser parser=newQueryParser(Version.LUCENE_45,defaultField,aWrapper);

是的……我知道……问题是最好的模糊结果往往出现在错误的国家。因此,对传入国家代码的模糊点击可能是第n次点击“down”。目前我正在检索大量的结果,然后扔掉那些没有正确代码的结果。希望有更好的办法我不太明白。使用,我看不出任何结果可能有错误的国家代码。我同意,但很明显,小国家代码字符串只是与其他字段中的搜索一起加权…我通过缓存“解决”了问题,只返回大量结果并过滤掉不匹配的国家代码。不,查询解析器不会因为必填字段很短而决定忽略它。我猜您正在使用
StandardAnalyzer
和一个默认的stopword集,其中包含单词“in”,这样搜索词就完全从查询中删除了。您的国家代码字段可能根本不应该进行分析。可以轻松地将不同的分析仪应用于不同的领域。谢谢,我使用的是standardanalyzer。我会调查的
QueryParser parser = new QueryParser(Version.LUCENE_45, luceneQueryString, geonamesAnalyzer);
  Query q = parser.parse(luceneQueryString);

  TopDocs search = geonamesSearcher.search(q, rowsReturned);
 FULL_NAME_ND_RO:india~ AND CC1:in
StandardAnalyzer(Version.LUCENE_45, new CharArraySet(Version.LUCENE_45, 0, true));
Map<String,Analyzer> analyzerPerField = new HashMap<String,Analyzer>();
analyzerPerField.put("CC1", new KeywordAnalyzer());

PerFieldAnalyzerWrapper aWrapper =
  new PerFieldAnalyzerWrapper(geonamesAnalyzer, analyzerPerField);

QueryParser parser = new QueryParser(Version.LUCENE_45, defaultField, aWrapper);