Reputation: 148
import pymongo
client = pymongo.MongoClient(host='localhost', port=27017)
db = client['db']
collection = db['foo']
data = [{ # doc 1
'foo': 'x',
'bar': 'y',
'baz': 'z'
},
{
# doc 2
'foo': 'a',
'bar': 'b',
'baz': 'c'
},
{ # doc 3
'foo': 'd',
'bar': 'a',
'baz': 'e'
}]
result = collection.insert_many(data)
I'm looking for a way to query the collection for the value 'a' without having to specify the field. Ideally it would be something like...
cursor = collection.find({'*': 'a'})
...where '*'
means that all fields should be queried and documents 2 and 3 in the above example code should be returned.
I can work around this, but I'm hoping there's a way to do it purely with Mongo commands to keep my code concise. I have looked through Mongo's documentation but can only query examples that match specific fields, not any field.
Upvotes: 1
Views: 5478
Reputation: 14287
This solution uses text search functionality. This requires creating a compound index on all the fields that are to be searched as a text index. In the example collection, below, the fields fld1
, fld2
, fld3
of the collection srch3
.
1. Sample collection:
{ _id: 1, fld1: "app", fld2: "ban", fld3: "pin" },
{ _id: 2, fld1: "gua", fld2: "ora", fld3: "kiw" },
{ _id: 3, fld1: "man", fld2: "ban", fld3: "pin" },
{ _id: 4, fld1: "pom", fld2: "lit", fld3: "fig" },
{ _id: 5, fld1: "app", fld2: "cus", fld3: "ora" }
2. Create text index:
db.srch3.createIndex( { fld1: "text", fld2: "text", fld3: "text" } )
3. Query:
db.srch3.find( { $text: { $search: "ora" } } )
Returns documents with _id
's 2
and 5
.
db.srch3.find( { $text: { $search: "cus" } } )
Returns document with _id
= 5
db.srch3.find( { $text: { $search: "ban" } } )
Returns documents with _id
's 3
and 1
.
db.srch3.find( { $text: { $search: "gas" } } )
No documents are matched.
This is a workaround solution. Create a dummy additional field with an array of all the field values for each document in the collection; e.g., foo_bar_baz
as in the example below. Query on this new field.
{ _id: 1,
'foo':'x',
'bar':'y',
'baz':'z',
'foo_bar_baz': [ 'x', 'y', 'z' ]
},
{ _id: 2,
'foo':'a',
'bar':'b',
'baz':'c',
'foo_bar_baz': [ 'a', 'b', 'c' ]
},
{ _id: 3,
'foo':'d',
'bar':'a',
'baz':'e',
'foo_bar_baz': [ 'd', 'a', 'e' ]
}
Query:
db.srch1.find( { foo_bar_baz: 'a' } )
The query returns the two documents with the _id
values 2
and 3
.
NOTE: This will require the application keep the field values with the foo_bar_baz
field in sync.
Upvotes: 0
Reputation: 4488
So I think you need an index to do that : https://docs.mongodb.com/manual/core/index-text/
After creating an index :
db.collection.createIndex( { "$**": "text" } ) #taken from docs
You can search it like this
cursor = collection.find({ $text: { $search: 'stringYouAreLookingFor' } });
Hope it helps
Upvotes: 1