2

現在、アプリにリアルタイム検索機能を実装していますが、混乱している動作に遭遇しました。

背景は次のとおりです。サーバー上の同じ MongoDB データベースから 2 つのサブスクリプションを持っていますposts

  1. 最初のサブスクリプションは、最新の 50 件の投稿をサブスクライブし、データを MiniMongo コレクションに送信しますPosts

  2. 2 番目のサブスクリプションは、ユーザーが入力した検索に一致する投稿をサブスクライブし、このデータを以下のように MiniMongo コレクションに送信しPostsSearchます。

    // client
    
    Posts = new Mongo.Collection('posts');
    
    PostsSearch = new Mongo.Collection('postsSearch');
    
    // server
    
    Meteor.publish('postsPub', function(options, search) {
    
        return Posts.find(search, options);
    
    });
    
    Meteor.publish('postsSearchPub', function(options, search) {
    
        var self = this;
    
        var subHandle = Posts.find(search, options).observeChanges({
    
            added: function (id, fields) {
    
                self.added("postsSearch", id, fields);
    
            }
    
        });
    
        self.ready();
    });
    

私の質問は、ドキュメントからわかっていることです:

コレクションを作成するときに名前を渡すと、永続的なコレクション (サーバーに保存され、すべてのユーザーに表示されるコレクション) が宣言されます。クライアント コードとサーバー コードはどちらも、同じ API を使用して同じコレクションにアクセスできます。

ただし、これは当てはまりませんPostsSearch。ユーザーがクライアントで検索を開始すると、機能は期待どおりに完全に機能し、正しいカーソルがクライアントに送信されます。

ただしpostsSearch、MongoDB データベースに a が表示されず、同様に、PostsSearch自分以外のクライアントにもデータが取り込まれていません。

これはどのように起こっていますか?カーソルをクライアントに送信することはself.added("postsSearch", id, fields);できますが、MongoDB データベースには送信できません。

4

2 に答える 2

1

このdocに従って、ドキュメントがコレクションに追加されたことをクライアント側にself.added("postsSearch", id, fields); 通知します。postsSeach

Meteor.publishによると:

または、発行関数は、追加された関数を呼び出すことによって、発行されたレコード セットを直接制御できます(発行されたレコード セットに新しいドキュメントを追加するため)。

だから私はself.added、これらの操作の両方を行うと推測しています: ドキュメントを公開されたレコード セットに追加し、クライアント (現在のパブリケーションを購読している) にこの追加を通知します。


Meteor.subscribeが表示された場合:

レコード セットをサブスクライブすると、クライアントにレコードを送信するようにサーバーに指示されます。クライアントは、これらのレコードをローカルの Minimongo コレクションに保存します。このコレクションの名前は、発行ハンドラーの追加、変更、および削除されたコールバックで使用されるコレクション引数と同じです。Meteor は、一致するコレクション名を使用してクライアントで Mongo.Collection を宣言するまで、着信レコードをキューに入れます。

これは2つのことを示唆しています:

  1. サーバー側のデータベースからデータを受け取るために必要です。subscribe

  2. postsSearchクライアントのみのコレクションを作成するには、何らかのクライアント側コードが存在する必要があります。(これは、このコレクションがサーバー側データベースに存在しないと言ったためです)。

2 番目のポイントは、次のように非常に簡単に達成できます。

if(Meteor.isClient) {
  postsSearch = new Mongo.Collection(null);
}

上記の例では、postsSearchコレクションはクライアントにのみ存在し、サーバーには存在しません。

1つ目に関しては、サブスクライブするpostsSearchPubと、コレクションのデータがクライアントに自動的に送信されpostsSearchます(サーバー側のデータベースにコレクションが存在しない場合でも。これは、への明示的な呼び出しによるものself.addedです)。


チェックアウトするもの:このドキュメントによると、サブスクリプションself.ready();のコールバックを呼び出します。onReadyこのコールバックに何が含まれているかを確認すると便利です。おそらく、クライアントのみのpostsSearchコレクションが定義されているのではないでしょうか?

于 2016-02-27T15:07:50.507 に答える
0

ドキュメントから:

this.added(collection, id, fields)

Call inside the publish function. 
Informs the subscriber that a document has been added to the record set.

これは、行がコレクションself.added("postsSearch", id, fields);に挿入が行われたという事実をエミュレートすることを意味しPostsSearchますが、明らかにそうではありません。

MongoDB コレクションがないことに関しては、最初の挿入時に MongoDB コレクションを作成する Meteor の遅延に関連している可能性がありますが、確かではありません。

于 2016-02-27T14:45:38.007 に答える