sql >> Database teknologi >  >> RDS >> Mysql

Opdag dublerede engelske navne

Jeg ville bruge et SynonymFilter på fornavnet under indeksering, så du har alle mulige kombinationer (Bob -> Robert, Robert -> Bob, osv...). Indekser de eksisterende brugere, du har.

Brug derefter QueryParser (uden SynonymFilter i analysatoren) til at stille nogle uklare forespørgsler.

Dette er koden, jeg fandt på:

public class NameDuplicateTests {
    private Analyzer analyzer;
    private IndexSearcher searcher;
    private IndexReader reader;
    private QueryParser qp;

    private final static Multimap<String, String> firstNameSynonyms;
    static {
        firstNameSynonyms = HashMultimap.create();
        List<String> robertSynonyms = ImmutableList.of("Bob", "Bobby", "Robert");
        for (String name: robertSynonyms) {
            firstNameSynonyms.putAll(name, robertSynonyms);
        }
        List<String> willSynonyms = ImmutableList.of("William", "Will", "Bill", "Billy");
        for (String name: willSynonyms) {
            firstNameSynonyms.putAll(name, willSynonyms);
        }
    }

    public static Analyzer createAnalyzer() {
        return new Analyzer() {
            @Override
            public TokenStream tokenStream(String fieldName, Reader reader) {
                TokenStream tokenizer = new WhitespaceTokenizer(reader);
                if (fieldName.equals("firstName")) {
                    tokenizer = new SynonymFilter(tokenizer, new SynonymEngine() {
                        @Override
                        public String[] getSynonyms(String s) throws IOException {
                            return firstNameSynonyms.get(s).toArray(new String[0]);
                        }
                    });
                }
                return tokenizer;
            }
        };
    }


    @Before
    public void setUp() throws Exception {
        Directory dir = new RAMDirectory();
        analyzer = createAnalyzer();

        IndexWriter writer = new IndexWriter(dir, analyzer, IndexWriter.MaxFieldLength.UNLIMITED);
        ImmutableList<String> firstNames = ImmutableList.of("William", "Robert", "Bobby", "Will", "Anton");
        ImmutableList<String> lastNames = ImmutableList.of("Robert", "Williams", "Mayor", "Bob", "FunkyMother");

        for (int id = 0; id < firstNames.size(); id++) {
            Document doc = new Document();
            doc.add(new Field("id", String.valueOf(id), Field.Store.YES, Field.Index.NOT_ANALYZED));
            doc.add(new Field("firstName", firstNames.get(id), Field.Store.YES, Field.Index.ANALYZED));
            doc.add(new Field("lastName", lastNames.get(id), Field.Store.YES, Field.Index.NOT_ANALYZED));
            writer.addDocument(doc);
        }
        writer.close();

        qp = new QueryParser(Version.LUCENE_30, "firstName", new WhitespaceAnalyzer());
        searcher = new IndexSearcher(dir);
        reader = searcher.getIndexReader();
    }

    @After
    public void tearDown() throws Exception {
        searcher.close();
    }

    @Test
    public void testNameFilter() throws Exception {
        search("+firstName:Bob +lastName:Williams");
        search("+firstName:Bob +lastName:Wolliam~");
    }

    private void search(String query) throws ParseException, IOException {
        Query q = qp.parse(query);
        System.out.println(q);
        TopDocs res = searcher.search(q, 3);
        for (ScoreDoc sd: res.scoreDocs) {
            Document doc = reader.document(sd.doc);
            System.out.println("Found " + doc.get("firstName") + " " + doc.get("lastName"));
        }
    }
}

Hvilket resulterer i:

+firstName:Bob +lastName:Williams
Found Robert Williams
+firstName:Bob +lastName:wolliam~0.5
Found Robert Williams

Håber det hjælper!




  1. Er databasetabeller sorteret før eller efter de er hentet?

  2. Hvordan kan jeg få MySQL til at skrive outfiler som en anden bruger?

  3. Flere While-løkker inden for en While-løkke?

  4. Postgresql venstre ydre joinforbindelse på json-array