Algolia: Filter on attribute with type boolean - algolia

In Algolia, I have the following object in index "users":
{
"name": "Jaap",
"objectID": 1,
"isActivated": true
}
I want to get all objects from index "users" where "isActivated" is true. How should the filter string look? I already tried "isActivated", "isActivated:true", "isActivated=true"... it all doesn't work.

Alright, I was impatient:
"isActivated=1"
This worked for me. Booleans are treated as numbers; true = 1 and false = 0.

Related

How to check an existence of the nested key in an object in MongoDB?

So the problem is that I must find the number of hotels in each state by using "aggregate" function and "group" operator in MongoDB. Hotels have to have at least 4.5 stars and have an attribute "Wi-Fi" with value true. I attached below the link to the image with structure of objects (screen from Robo3T)
"attributes" is a key of the business collection and it can have nested keys like "Wi-Fi" but it is not necessary. I don't know how to check an existence of this key along with true value. I wrote some code but without checking it (see below).
db.business.aggregate([
{$match: {"categories": {$in: ["Hotels"]}, "stars":{$gte: 3.5}}},
{$group: {_id:"$state", count:{$sum:1}}}])
I need help with this example and a lot explanation.
you don't need to check the existence of some field as long as you need to check that this field is true
so, just add 'attributes.Wi-Fi': true to the match object
so the query should be
'attributes.Wi-Fi': true
if you need to check that some attribute like Wi-Fi does not exist or equal to false
then the query should be like
1-
'attributes.Wi-Fi': { $ne: true } // wi-fi attribute is not equal to true, this means either wi-fi does not exist or exists but equals any value but not true
2- or using the $or operator
$or: [
{
'attributes.Wi-Fi': { $exists: false } // wifi attribute does not exist
},
{
'attributes.Wi-Fi': false // or exists and equal to false
}
]
just add any of these queries if needed to the $match object

what the difference between item: {$exists:false} and item : null?

What is the difference by doing :
"AnArray.fieldA":null
and
"AnArray.fieldA":{$exists:false}
And why on documents like
{
AnArray:[
{},
{fieldA:1}
]
},
{
AnArray:[
{fieldA:3},
{fieldA:1}
]
}
"AnArray.fieldA":null return me the first one doc but "AnArray.fieldA":{$exists:false} return me no doc :(
It's nicely explained here.
The { item : null } query matches documents that either contain the item field whose value is null or that do not contain the item field.
So your first query returns the document if there's any subdocument in AnArray with missing fieldA
$exists works in a different way. "AnArray.fieldA" is interpreted as an array of values taken from specified path. For your documents it is: [null, 1] and [3,1]. So as long as there's at least one fieldA $exists will return true and as you expect it to return false you're getting no results.

Is there a mongo query that returns a boolean if any documents match a query? [duplicate]

I want to return true if a userID already exists and false otherwise from my collection.I have this function but it always returns True.
def alreadyExists(newID):
if db.mycollection.find({'UserIDS': { "$in": newID}}):
return True
else:
return False
How could I get this function to only return true if a user id already exists?
Note: This answer is outdated. More recent versions of MongoDB can use the far more efficient method db.collection.countDocuments. See the answer by Xavier Guihot for a better solution.
find doesn't return a boolean value, it returns a cursor. To check if that cursor contains any documents, use the cursor's count method:
if db.mycollection.find({'UserIDS': { "$in": newID}}).count() > 0
If newID is not an array you should not use the $in operator. You can simply do find({'UserIDS': newID}).
Starting Mongo 4.0.3/PyMongo 3.7.0, we can use count_documents:
if db.collection.count_documents({ 'UserIDS': newID }, limit = 1) != 0:
# do something
Used with the optional parameter limit, this provides a way to find if there is at least one matching occurrence.
Limiting the number of matching occurrences makes the collection scan stop as soon as a match is found instead of going through the whole collection.
Note that this can also be written as follow since 1 is interpreted as True in a python condition:
if db.collection.count_documents({ 'UserIDS': newID }, limit = 1):
# do something
In earlier versions of Mongo/Pymongo, count could be used (deprecated and replaced by count_documents in Mongo 4):
if db.collection.count({ 'UserIDS': newID }, limit = 1) != 0:
# do something
If you're using Motor, find() doesn't do any communication with the database, it merely creates and returns a MotorCursor:
http://motor.readthedocs.org/en/stable/api/motor_collection.html#motor.MotorCollection.find
Since the MotorCursor is not None, Python considers it a "true" value so your function returns True. If you want to know if at least one document exists that matches your query, try find_one():
#gen.coroutine
def alreadyExists(newID):
doc = yield db.mycollection.find_one({'UserIDS': { "$in": newID}})
return bool(doc)
Notice you need a "coroutine" and "yield" to do I/O with Tornado. You could also use a callback:
def alreadyExists(newID, callback):
db.mycollection.find_one({'UserIDS': { "$in": newID}}, callback=callback)
For more on callbacks and coroutines, see the Motor tutorial:
http://motor.readthedocs.org/en/stable/tutorial.html
If you're using PyMongo and not Motor, it's simpler:
def alreadyExists(newID):
return bool(db.mycollection.find_one({'UserIDS': { "$in": newID}}))
Final note, MongoDB's $in operator takes a list of values. Is newID a list? Perhaps you just want:
find_one({'UserIDS': newID})
One liner solution in mongodb query
db.mycollection.find({'UserIDS': { "$in": newID}}).count() > 0 ? true : false
return db.mycollection.find({'UserIDS': newID}).count > 0
This worked for me
result = num.find({"num": num}, { "_id": 0 })
if result.count() > 0:
return
else:
num.insert({"num": num, "DateTime": DateTime })

Mongo aggregate and count over n fields

Im having trouble understanding MongoDB's Aggregation framework. Basically my JSON looks like this:
[
{
"id": 1,
"param1": true,
"param2": false,
"param3": false
},
{
"id": 2,
"param1": true,
"param2": false,
"param3": true
},
{
"id": 3,
"param1": false,
"param2": true,
"param3": false
}
]
I want to count how many documents have, for example, param1 == true, param2 == true and so on.
In this case the expected result should be:
count_param1: 2
count_param2: 1
count_param3: 1
The trick here is that param can be param1 .. paramN, so basically I either need to do a distinct and specify exactly which fields im interested in or can I "group on" all fields starting with "param".
What is the recommended approach?
Further explanation:
The SQL equivalent would be to do:
SELECT COUNT(param1) AS param1
FROM [Table]
GROUP BY param1
For each column (but in one query).
I would not use aggregation, as there is a built-in helper count() for this:
> db.collection.count({ "param1" : true })
You can create a simple function that takes the parameter name as argument and gives back the count:
> param_count = function(param_name) {
count_obj = {}
count_obj[param_name] = true
return db.collection.count(count_obj)
}
While it is technically possible to get the counts for all the params in one aggregation pipeline, it's infeasible for 1 million+ rows and it will be better to do one aggregation pipeline per param name. I'm not well-versed in SQL, but I am guessing when you give the SQL equivalent and say you'd do them all in "one query" you mean you'd send one batch of SQL but it would essentially be a concatenation of different queries to group and count, so it's not much different from the solution I have given.
The count can use an index on paramN if one exists.
This has been solved.
Check out my related question and chridam's excellent answer.
A perfect solution for my needs.

Using MongoDB Covered Index

This is in relation to the MongoDB manual at http://docs.mongodb.org/manual/core/query-optimization.
I am not understanding the purpose of Covered query. If we have a collection with index on the type and item fields like given below
{ type: 1, item: 1 }
and if the query is like this
db.inventory.find( { type: "food", item:/^c/ },
{ item: 1, _id: 0 } )
This will return only item? Why does it only return item? The second part of the MongoDB query
after the find part i.e.
{ item: 1, _id: 0 } )
what does it signify? What is 0 and 1?
Why does the query below returns both item and id?
db.inventory.find( { type: "food", item:/^c/ },
{ item: 1 } )
refer to the document of db.collection.find, it says very clear, the 2nd parameter is about which filed to return:
Optional. Specifies the fields to return using projection operators. To return all fields in the matching document, omit this parameter.
You can use those projection operators of course. But most of the time we just specify which fields to return and which fields are not. So
{ item: 1, _id: 0 }
means result set should only contain the field item, not _id (because id defaults to be in the result set unless you say no).
Also note in JavaScript world, 1/0 also means true/false. If it helps you to understand. Thus:
1 == true // true
0 == false // true
It's because of the auto conversion in JavaScript. And if you don't want the conversion,
1 === true // false