2017-11-03 11 views
0

모음에 단어 목록을 삽입하는 Java 함수를 작성하려고합니다. 고유 한 필드 "단어"가있는 각 단어에 대해 하나의 문서를 원합니다. 삽입하려는 단어 목록에 여러 개의 중복이 포함되어 있으므로 컬렉션에 동일한 "단어"값이있는 문서가없는 경우에만 문서에 삽입하는 기능이 필요합니다. 동일한 "단어"값을 가진 문서가 이미있는 경우이 함수는이 문서를 바꾸거나 바꾸지 말고 목록에서 다음 단어를 삽입해야합니다.MongoDB Java Driver : 문서가없는 경우 문서를 삽입하십시오. else do nothing

중복 된 문서를 피하고 중복 키 예외를 잡기 위해 "단어"필드에 색인을 만들었지 만 이것이이 문제를 처리하는 올바른 방법인지는 확실하지 않습니다.

IndexOptions uniqueWord = new IndexOptions().unique(true); 
    collection.createIndex(Indexes.ascending("word"), uniqueWord); 


     try { 
      File file = new File("src/words.txt"); 
      Scanner scanner = new Scanner(file); 


      while (scanner.hasNextLine()) { 
        String word= scanner.next(); 

        Document document = new Document(); 
        document.put("word", word); 

        InsertManyOptions unordered= new InsertManyOptions(); 
        ArrayList<Document> docs = new ArrayList<>(); 
        docs.add(document); 

        try{ 
        collection.insertMany(docs, unordered.ordered(false)); 
        }catch(Exception e){ 
         //System.out.println(e.getMessage()); 
        } 
+1

스크립트를 표시하십시오. – yacc

+0

단어 필드에 고유 색인을 추가하려고 시도 했습니까? –

답변

0

당신이 쓴 :

이미 같은 "단어"변경하거나 문서를 대체하지만 내 목록에서 다음 단어를 삽입에 가지 말았어야 기능을 - 가치가있는 문서가 있다면.

이것은 원자 조작 upsert: true와 같은 findOneAndUpdate 또는 findOneAndReplace의 사용을 배제한다. 당신의 작가가 멀티 스레드 예를 들어, 경우

if (collection.count(Filters.eq("word", "..."))) { 
    // insert 
} else { 
    // ignore because there is already a document for this word 
} 

이 가능한 경주 조건이 적용됩니다

대신, 나는 당신의 옵션과 같은 사전 쓰기 검사로 제한됩니다 생각 한 스레드가 collection.count()의 잘못된 결과에 반응하는 동안 다른 스레드가 그 단어에 대한 항목을 쓰는 것을 관리합니다. 의 findOneAndReplace 원자이다 그래서 그 문제 경향이되지 않습니다

난 당신이 FindOneAndReplaceOptions.upsert == truefindOneAndReplace를 사용하는 것이 좋을 것

, 이것은 교체하여 이미 기록 된 문서를 (이기는하지만 무시와 같은 최종 결과를해야합니다 동일한 문서로). 그러나 아마도 write-if-exists 검사를 적용하는 것보다 안전 할 것입니다.

업데이트 편집 된 질문은 당신이 많은 삽입 '하고 있지만 루프 주위 때마다 만 (collection.insertMany()를 사용에도 불구하고) 하나의 문서를 삽입하므로 위의 제안은 여전히 ​​유효하다는 것을 의미한다. 예 :

while (scanner.hasNextLine()) { 
    String word= scanner.next(); 

    if (collection.count(Filters.eq("word", word)) == 0L) { 
     Document document = new Document(); 
     document.put("word", word); 

     collection.insertOne(document); 
    } 
}