2011-11-23 17 views
16

このシナリオではPymongoを使用します。Mongodb - 複数のフィールドで文字列を検索するには?

私はemail、first_name、last_nameを持つUserを持っています。

私はこのPymongoスニペットを使用しています

user_found = users.find({'$or':[ 
      {'email':{'$regex':searchString, '$options':'i'}}, 
      {'first_name':{'$regex':searchString, '$options':'i'}}, 
      {'last_name':{'$regex':searchString, '$options':'i'}}]}) 

この例では動作しますが、私は検索文字列検索する場合:

  • 電子メール、または
  • first_nameの、または
  • LAST_NAME

今私はまた、first_name + last_nameを組み合わせたsearchStringが見つかりました。

どうすればいいですか? mongoにはクエリを介して2つを結合して "フルネーム"とし、フルネームを検索する方法はありますか?

答えて

13

最も簡単な方法は、配列フィールドを追加して、検索するすべてのバリアントを入力することです。その配列フィールドのインデックスを作成します。

このように、インデックスを1つだけ必要とし、すべてのフィールドで検索するのは簡単で、新しい検索バリアントを検索する場合は変更されません。にMongoDBのドキュメント今keyword searchと新full-text search機能をカバーして:あなたはまた、

などの句読点の除去、例えばあなたが検索配列に入れ、テキスト、下部ケーシングそれを正規化することができます https://stackoverflow.com/q/8206188/224370

編集を参照してください。

+1

大変簡潔な答え –

+0

@lanマーサー私の検索は複数のフィールドでうまくいきました。結合された[fname + sname]フィールドの検索、両方のフィールドのインデックスを作成して完了する必要はありますか? –

+0

@AqibMumtazあなたがしようとしていることの例で新しい質問を投稿してください - コメントは新しい質問をするのに最適な場所ではありません。 –

0

私は同じ問題を抱えていました。私はすでに正規表現の文字列検索を使用していたので、私の解決策は:

ヘルパーコレクションを生成します。私はその後、私が探したことを可能にするものをクリートするために正規表現を使用し

{ 
    search_field: email + " " + first_name + " " + last_name, 
    ref_id: (id to real object) 
} 

:ここで私は次のように、関連するすべての文字列を組み合わせ

// logic found here: http://stackoverflow.com/questions/10870372/regex-match-if-string-contain-all-the-words-or-a-condition 
var words = query.split(/[ ,]+/); 
var regstr = ""; 
for (var i = 0; i < words.length; ++i) { 
    var word = words[i]; 
    regstr += "(?=.*?\\b" + word + ")"; 
} 
regstr += "^.*$"; 
regex = new RegExp(regstr, "i"); 

これは、その後も順序に関するいくつかの柔軟性を提供します。

すべての要素で正規表現が使用されているので、検索は最も高速ではありませんが、私にとっては問題ありません。 (私もインデックスsearch_fieldのコレクションを最初に、あなたが本当にしたい_idsを取得する必要がありますので、

の取得結果はまた、ネストされたコールとなり、その後、あなたがそうのようにそれらを照会することができます。

connection.find({ "search_field" : regex }, { _id: 0, ref_id: 1 }, { limit: limit, skip: start }).toArray(function (err, docs) { 
    if (err) throw err; 
    // map array of documents into simple array of ids 
    var ids = []; 
    for (var i = 0; i < docs.length; ++i) 
    { 
     var doc = docs[i]; 
     ids.push(doc.ref_id); 
    } 
    if (ids.length > 0) 
     MongooseEmails.find({ "_id": { $in: ids } }, function (err, docres) { 
      if (err) throw err; 
      res.send(JSON.stringify(docsres)); 
     }); 
    else 
     res.send(""); 
}); 

これは編集されたコードです..構文エラーがありますが、一般的には私のために働いています

関連する問題