Using pymongo I am trying to retrieve the documents in a collection that have a SmallUrl different from null. I'm trying to get the names key and the SmallUrl key.
If I look for the Name only, the query runs fine. However, since I want to filter out from the results the documents that have a null value for SmallUrl, when I include the this in the query, the query returns nothing.
This is the MongoDB structure:
{u'Images': {u'LargeUrl': u'http://somelink.com/images/7960/53.jpg',
u'SmallUrl': u'http://somelink.com/images/7960/41.jpg'}
u'Name': u'Some Name',
u'_id': ObjectId('512b90f157dd5920ee87049e')}
{u'Images': {u'LargeUrl': u'http://somelink.com/images/8001/53.jpg',
u'SmallUrl': null}
u'Name': u'Some Name Variation',
u'_id': ObjectId('512b90f157dd5820ee87781e')}
This is the function for the query:
def search_title(search_title):
$ne
''' Returns a tuple with cursor (results) and the size of the cursor'''
query = {'Name': {'$regex': search_title, '$options': 'i'}, 'SmallUrl': {'$exists': True}}
projection = {'Name': 1, 'Images': 1}
try:
results = movies.find(query, projection)
except:
print "Unexpected error: ", sys.exc_info()[0]
$ne
return results, results.count()
I am new to MongoDB I tried different queries already. I have used $and, $not, {'$ne': 'null'}}. I also ran the queries in the mongoShell, but same result. This is an example of what I have queried in the shell:
db.myCollection.find({'Name': {'$regex': 'luis', '$options': 'i'}, 'SmallUrl': {'$ne': null}})
I would like to know what I am doing wrong.
The pymongo version of null is the Python None. So query should look like:
query = {
'Name': {'$regex': search_title, '$options': 'i'},
'Images.SmallUrl': {'$ne': None}}
your query does not work because you should use 'Images.SmallUrl' instead of 'SmallUrl' for the key of query.
my test collection:
> db.t.find()
{ "_id" : ObjectId("512cdbb365fa12a0db9d8c35"), "Images" : { "LargeUrl" : "http://aaa.com", "SmallUrl" : "http://bb.com" }, "Name" : "yy" }
{ "_id" : ObjectId("512cdc1765fa12a0db9d8c36"), "Images" : { "LargeUrl" : "http://aaa.com", "SmallUrl" : null }, "Name" : "yy" }
and my test query:
> db.t.find({'Images.SmallUrl': {$ne: null}})
{ "_id" : ObjectId("512cdbb365fa12a0db9d8c35"), "Images" : { "LargeUrl" : "http://aaa.com", "SmallUrl" : "http://bb.com" }, "Name" : "yy" }
Hope to help ^_^
Related
I have the below query
db.getCollection('DOCUMENT1').find(
{"FIELD1":
{
"$in":[
1234567,
7654321
]
}
} , "$and": [{
"FIELD2" : { $exists : true }
}]
,{"FIELD1" : 1, "FIELD2" : 1} )
When I execute the above query , I get the below error:
Error: Line 9: Unexpected token :
I get only the documents that matches "Field1". Using $in, from the obtained document, I want to check if another field (FIELD2) exists and if exists, I want to display the value of that field. How can I achieve that?
It should be something like this :
db.getCollection('YourCollectionName').find({$and :[{field1: {$in:[1234567, 7654321]}},{field2:{$exists: true}}]},
{field1:1, field2:1, _id:0})
Your query has syntax errors & also $and is an array that takes in multiple filters, which has to be given in place of filterQuery of .find() . Ex :- .find(filterQuery, projectQuery)
One of my collection no longer returns anything on some search values. Here is a console dump to illustrate the probleme :
meteor:PRIMARY> db['test'].insert({ sku: 'Barrière' });
WriteResult({ "nInserted" : 1 })
meteor:PRIMARY> db['test'].insert({ sku: 'Bannière' });
WriteResult({ "nInserted" : 1 })
meteor:PRIMARY> db['test'].createIndex({ sku: 'text' });
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
meteor:PRIMARY> db['test'].find({ sku: /ba/i });
{ "_id" : ObjectId("57bbb447fc77800b1e63ba64"), "sku" : "Barrière" }
{ "_id" : ObjectId("57bbb455fc77800b1e63ba65"), "sku" : "Bannière" }
meteor:PRIMARY> db['test'].find({ $text: { $search: 'ba' } });
meteor:PRIMARY> db['test'].find({ $text: { $search: 'Ba' } });
meteor:PRIMARY>
The search returned nothing, even though I clearly added two documents that should match. What's going on? What option/config am I missing?
** Edit **
I tried this query
meteor:PRIMARY> db['test'].find({ $or: [ { $text: { $search: 'ba' } }, { sku: { $regex: 'ba', $options: 'i' } } ] });
Error: error: {
"waitedMS" : NumberLong(0),
"ok" : 0,
"errmsg" : "error processing query: ns=meteor.testTree: $or\n sku regex /ba/\n TEXT : query=ba, language=english, caseSensitive=0, diacriticSensitive=0, tag=NULL\nSort:
{}\nProj: {}\n planner returned error: Failed to produce a solution for TEXT under OR - other non-TEXT clauses under OR have to be indexed as well.",
"code" : 2
}
But I'm not sure how I can make an index to search partial values (i.e. using $regex or other operator). Using a third party indexer seems overkill to me... Surely there is a way to perform a full-text search, as well as a pattern match at once?
Is my only solution to perform two queries and merge the results manually?
Try this:
db['test'].insert({ sku: 'ba ba' });
db['test'].find({ $text: { $search: 'ba' } });
Also refer to mongodb document:
If the search string is a space-delimited string, $text operator performs a logical OR search on each term and returns documents that contains any of the terms.
I think mongodb $text $search just split the string by space and match the whole word. If you need to search part of the word, you may need to use some other framework for help. Maybe you can also use $regex to do this.
If the only requirement is to query the word by prefix, you can use $regex, it can use index if you are only querying by the prefix. Otherwise if will scan the whole collection.
I am trying to update multiple nested documents in a document in mongoDB.
Say my data is:
{
"_id" : "ObjectId(7df78ad8902c)",
"title" : "Test",
"img_url" : "[{s: 1, v:1}, {s: 2, v: 2}, {s: 3, v: 3}]",
"tags" : "['mongodb', 'database', 'NoSQL']",
"likes" : "100"
}
I want to update v to 200 for s = 1 and s= 2 in img_url list.
It is easy to update v for any single s.
Is there any way to update multiple documents satisfying some criteria.
I tried:
db.test.update({ "_id" : ObjectId("7df78ad8902c"), "img_url.s": {$in : ["1", "2"]}}, {$set: { "img_url.$.v" : 200 } });
and
db.test.update({ "_id" : ObjectId("7df78ad8902c"), "img_url.s": {$in : ["1", "2"]}}, {$set: { "img_url.$.v" : 200 } }, {mulit: true});
Some sources are suggesting it is not possible to do so.
Multiple update of embedded documents' properties
https://jira.mongodb.org/browse/SERVER-1243
Am I missing something ?
For the specific case/example you have here. You are specifying an _id which means you are to update only one with that specific _id.
to update img_url try without the _id; something like this:
db.test.update({}, {"$set":{"img_url.0":{s:1, v:400}}}, {multi:true})
db.test.update({}, {"$set":{"img_url.1":{s:2, v:400}}}, {multi:true})
0 and 1 in img_url are the array indexes for s:1 and s:2
in order to update based on specific criteria you need to set the attribute you need on the first argument. say for example, to update all documents that have likes greater than 100 increment by 1 you do (assuming likes type is int...):
db.people.update( { likes: {$gt:100} }, {$inc :{likes: 1}}, {multi: true} )
hope that helps
Please consider the following document, a part of the Runtime collection:
{
"entity_id" : 10,
"features" : [
{
"10" : "Test System 2"
},
{
"20" : "System 2 Description"
},
{
"180" : ISODate("2013-12-25T18:19:40.589Z")
},
{
"190" : ISODate("2013-12-25T18:19:40.589Z")
}
],
"_id" : ObjectId("52bb21bc8a2ebdc01c000001")
}
My goal is to update the value of the element of the "features" array having the key "20".
Here are the things I've tried (in mongo shell):
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features.$.20":"Updated Description"}}} );
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features['20']":"Updated Description"}}} );
db.Runtime.findAndModify({ "query" : {"_id": "52bb21bc8a2ebdc01c000001"}, "update" : {$set : {"features[1]":"Updated Description"}}} );
In all instances the shell prints
null
and nothing happens to the data. So, the main question is, of course, what is wrong with my code snippets. Also, how that "null" is supposed to get interpreted? And is there such a thing as mongo shell's log where one could find any clues? Many thanks for your help!
When using the $ positional operator in an update, your query needs to include a term that matches the element of the array you're updating:
db.Runtime.findAndModify({
query: {_id: ObjectId("52bb21bc8a2ebdc01c000001"),
'features.20': {$exists: true}},
update: {$set: {"features.$.20":"Updated Description"}}
})
Note that you also need to call ObjectId on your _id string to turn it into an actual ObjectId or it won't match the doc.
I have a dataset that looks like this:
{ "_id" : ObjectId( "----number-----" ),
"interaction" : { "author" : { "link" : "------",
"avatar" : "----link---",
"name" : "-----name----",
"id" : "12345678" },
How do I query mongodb to give me a list of id's from this sort of field? If you know, I also need to group them descending by count. Is there an equivalent of group by as in sql?
Thanks!
Look into the MongoDB Aggregation Framework.
The query you're looking for should be like this.
db.collection.aggregate([{$group: {_id: '$iteraction.id', hits: {$sum: 1}}}, {$sort: {hits: -1}}])