2017-11-05 9 views
0

ドメイン駆動型デザインの後、スタックオーバーフローのようなウェブサイトの検索コンテキストをどのようにモデル化できますか?ドメイン駆動型デザインの検索コンテキスト

私のドメインでは、質問、回答、質問のタグとして3つのタイプのエンティティがあります。 検索文字列を受け取り、一致する質問、回答、タグを返すように検索コンテキストをモデル化する必要があります。

私は検索コンテキストでは、検索は検索を実行しますか、一部の企業はそこにすることができますちょうどDDD-サービスになるだろう、ということを理解したい

、骨材など

マッチングアルゴリズムであると仮定することができます単純なSQLのようなクエリ。

+0

私はあなたの質問が広すぎると考えています。あなたはもっと具体的になりますか?おそらく、いくつかのコードを提供し、特定の質問をしてください。 – w0051977

+0

私は何を提供するか分かりません。私の質問はもう少し幅広く、私は検索コンテキストのために演奏中のトップレベルのクラスを理解したい。私は説明を少し変更しました、それは助けてくれるかもしれませんし、親切に私が提供できる詳細を提案するかもしれません。 –

+0

私はあなたが求めているのは、スタックオーバーフローの知的財産だと思います。 DDDにはたくさんの良い本があります。おそらくあなたはそれらを買うことができますか?学習した概念を適用することができます。 – w0051977

答えて

0

おそらく、検索境界付きコンテキストのDDD戦術パターンの配列全体は必要ありません。検索設定の保存や検索テンプレートの作成を計画している場合を除いて、多分、それは非常に紛らわしいようです。

検索コンテキストが他のBCのデータにインデックスを付けたり、データにアクセスする方法を設計することはより複雑な問題になります。

+0

私は、検索可能なエンティティが変更され、検索コンテキストがそれらのイベントを購読して更新するたびに、他のBCがイベントを発行できると考えていました。環境設定やテンプレートを保存していないと仮定しましょう。私は、 "検索クエリ"、 "ページ番号"、 "ソーター"、 "適用フィルタ"などのようなデータを含むことができる "searchRequest"と呼ばれるオブジェクトがあると思っています。 )は検索結果を生成することができます。しかし、この "seachRequest"オブジェクトは何であろうか、エンティティではない(アイデンティティを持たない)。他の方法はありますか? –

+0

イベントの部分は、私の現在のチームでやっていることです。検索サービスは、それらのイベントをリッスンし、興味のあるデータを抽出し、内部のLuceneインデックスを更新します。私が言っていたように、検索サービスにはDDDパターンを使う必要はないので、リポジトリやエンティティなどはありません。基本的に読み取り専用のコンテキストなので、CQRSで行われたことから簡単な読み込みでインスピレーションを得ることができますモデル。 – guillaume31

1

クエリサービスで検索を実装する必要があります。

CQRSあなたがコマンドを使用するモデルを更新したい場合ので、そのようなあなたの場合のように、DDDで本当に良いフィット:

AnswerToQuestionCommand、PostNewQuestionCommandなど

をこれらのコマンドは、アプリケーションのサービスに送信されますエンティティを更新します。エンティティは、六角形のアーキテクチャでインターセプトされ、検索インデックスを更新するDomainEventを送信します。六角形のアーキテクチャでは、同じトランザクション内でインデックスを維持するために専用のサービスを呼び出すことで実行できます。たとえば、インデックスも更新されている場合は、エンティティが永続化されているとみなされます。私はこのように行くだろう。あなたはクエリサービスを経るなど、あなたの質問、回答、照会する必要がある場合はここで

は春@TransactionalEventListener

@Component 
public class ProjectRenamedListener { 

    @Value("${spring.jpa.properties.hibernate.search.default.indexBase:target}") 
    private String indexBase; 

    private final Logger logger = LoggerFactory.getLogger(ProjectRenamedListener.class); 

    @TransactionalEventListener 
    public void projectRenamed(final ProjectRenamed event) { 

     try (final StandardAnalyzer analyzer = new StandardAnalyzer(); 
      final Directory directory = NIOFSDirectory.open(Paths.get(indexBase, ProjectData.class.getName())); 
      final IndexWriter writer = new IndexWriter(directory, new IndexWriterConfig(analyzer))){ 

      final Document document = new Document(); 
      document.add(new StringField("project_id", event.projectId().identity(), Field.Store.YES)); 
      document.add(new StringField("tenant_id", event.tenant().identity(), Field.Store.YES)); 
      document.add(new TextField("name", event.name(), Field.Store.YES)); 
      writer.updateDocument(new Term("project_id", event.projectId().identity()), document); 
     } catch (IOException e) { 
      logger.warn("Unable to update index for project name.", e.getMessage()); 
     } 
    } 
} 

のサンプルです。インデックスを尋ね、クライアントに返すエンティティを読み込みます。

これの美しさは、それを変更して照会するときに同じオブジェクトである必要はないということです。コードの重複のために始めるとちょっと聞こえるが、長期間に渡って読み込み/クエリの操作が頻繁に起こって高速でなければならないので、明らかに優れた解決策であり、 ontは特別に超高速でなければなりません。私は、クエリサービス(https://github.com/VaughnVernon/IDDD_Samples)にヴォーンバーノンのアプローチを示唆し

、私はクエリサービスのための私の部分にはLuceneを使用し、ここでいくつかのコードは次のとおりです。

@PreAuthorize("hasAuthority('Administrator')") 
public Page<ProjectData> searchProjectsData(
     final String tenantId, 
     final String queryText, 
     final Pageable pageable) { 

    if (!StringUtils.isEmpty(tenantId)) { 
     return this.searchProjectsDataOfTenant(tenantId, queryText, pageable); 
    } 

    final StandardAnalyzer analyzer = new StandardAnalyzer(); 
    final QueryBuilder builder = new QueryBuilder(analyzer); 
    final Query query = builder.createPhraseQuery("name", queryText); 

    try { 
     final IndexReader reader = DirectoryReader.openIfChanged(this.directoryReader); 
     final IndexSearcher searcher = new IndexSearcher(reader); 
     final TopDocs documents = searcher.search(query, pageable.getPageSize()); 
     return this.fetchProjectsData(searcher, documents, pageable); 
    } catch (IOException e) { 
     throw new RuntimeException(String.format("Unable to search project for query: %s", queryText), e); 
    } 
} 
+0

EDIT:六角形アーキテクチャの検索メンテナンスインデックスを追加し、インデックス更新をトリガーするDomainEventを追加しました。 DDDのほうがはるかに優れています。 –

関連する問題