web-dev-qa-db-ja.com

MongoDBで複数の値の複数のフィールドを検索する

特定の文字列がいくつかのフィールドのいずれかに表示されるMongoDBコレクションがあります。

_{"_id":1, "field1":"foo","field2":"bar","field3":"baz", "otherfield":"stuff"},
{"_id":2, "field1": "bar", "field2": "baz", "field3": "foo", "otherfield":"morestuff"},
{"_id":3, "field1": "baz", "field2": "foo", "field3": "bar", "otherfield":"you get the idea"}
_

一連のフィールドのいずれかが配列内の任意の値に等しいすべてのレコードが返されるようにクエリする必要があります...基本的に、_["foo","bar"]_がある場合は、これらの文字列のいずれかfield1またはfield2にあります(ただし、他のフィールドはありません)。

明らかに、一連の複数のクエリでこれを行うことができます

db.collection.find({"field1":{"$in":["foo","bar"]}})db.collection.find({"field2":{"$in":["foo","bar"]}})

など、また、私はそれらをすべて連結する非常に大きな$ orクエリを作成しましたが、それはあまりにも効率が悪いようです(私の実際のコレクションは、9つのフィールドのいずれかで発生する15の文字列のいずれかに一致する必要があります)...しかし、私はまだnosql DBに慣れていないので、ここで使用する必要がある最高のパラダイムがわかりません。どんな助けも大歓迎です。

17
jlmcdonald

スイートスポットに当てはまると思われるドキュメントを熟読することで、テキストインデックスという別の答えが見つかりました。

db.collection.ensureIndex({"field1":"text","field2":"text"})
db.records.runCommand("text",{search:"foo bar"})

さらに多くの文字列とフィールド(および約100,000レコード)で実際のクエリを実行すると、$or/$inアプローチには620ミリ秒かかりますが、テキストインデックスには131ミリ秒かかります。 1つの欠点は、結果として異なるタイプのドキュメントを返すことです。幸いなことに、実際のドキュメントは各結果オブジェクトのパラメーターです。

時間をかけて提案してくれた人々に感謝します。

6
jlmcdonald

試してみる

db.collection.find(
    // Find documents matching any of these values
    {$or:[
        {"field1":{"$in":["foo","bar"]}},
        {"field2":{"$in":["foo","bar"]}}
    ]}
)

これも参照してください question

25
a14m

次のような値を追加することにより、関連するすべてのフィールドを1つのフィールド(つまり、collected)に収集します。

"foo:field1", 
"bar:field2", 
"baz:field3",  
"stuff:otherfield", 
"bar:field1", 
"baz:field2"
...

その分野に。

任意のフィールドに存在するbarを検索する場合、次を使用できます。

db.collection.find( { collected: { $regex: "^bar" } }, ... );

質問の例は次のようになります。

db.collection.find( collected: { { $all: [ "foo:field1", "foo:field2", "bar:field1", "bar:field2" ] } }, ... ); 
0
heinob