How do I facet filter on a negative number? - algolia

I am trying facet/filter on an attribute that has integer values. Positive values work fine, but Algolia is treating the minus sign as negation instead of part of the value.
So for the filter:
facetFilters: "category_id:-1
it returns all records that have a category_id other than 1.
I've tried quoting the value category_id:'-1' without luck. Is there a way to escape or disable the negation on facet filters to allow for filtering on negative values?

If your facet value starts with a '-' then you can escape the character with a \ to prevent the engine from interpreting this as a negative facet filter.
For example, filtering on category_id:-1 will filter on all records that have a category_id equal to “-1”.

Related

Firestore not-equal (!=) count as range filter

I'm trying to use the not-equal (!=) operator in a query that already has a range filter (geohash query), thinking this should behave the same as an equal (==) query.
But upon running that query, I get prompted with this error message:
Unhandled Exception: The initial orderBy() field "[[FieldPath([location, geohash]), false]][0][0]" has to be the same as the where() field parameter "FieldPath([expire_at])" when an inequality operator is invoked.
Now, I understand that, due to how indexes works, firestore only allow ONE range filter per query. What I don't understand is why the not-equal operation here is considered a range filter.
In other words: Is the not-equal operation just synthetic sugar for .where(x > y).where(x < y) ?
orderBy is used to help filter and process the index's so you get the most relevant to your needs. So the error is that the fields for the orderBy must be related to the where inequality field.
You must use an orderBy on the inequality field first, just make sure the correct compound queries are generated.

Why mongodb includes the value outside the range while querying with gt and lt?

I am trying to fetch some data within the range using gt and lt filter in mongodb but it's behaving strangely and I don't understand why it's containing the data below the range. Is it because the field is string? Also, If I am putting some random large value for lt like 50000 and gt as 1, it should return all the fields, but it's only returning some records. I am new to mongodb but it should be like other databases. And I am unable to find where I am going wrong.
You're right, it's because the field "price" is string. And string is compared using dictionary order. In this document, we can find how string is compared.
The algorithm to compare two strings is simple:
Compare the first character of both strings.
If the first character from the first string is greater (or less) than the other string’s, then the first string is greater (or less) than the second. We’re
done.
Otherwise, if both strings’ first characters are the same,
compare the second characters the same way. Repeat until the end of
either string.
If both strings end at the same length, then they are
equal.
Otherwise, the longer string is greater.
For example, in your result, there is a document with price is "80", which should not be there. Running the algorithm above to compare "120" and "80", we have :
Compare the first character of both strings: "1" < "8". So "120" < "80", that's why the document is presented in the result. (you can run the algorithm to find out that "80" < "800")
I suggest, if possible, you should store price as "Number" type in MongoDB. Then you will be able to use number comparision like you wish.

MongoDB multiple type of index on same field

Can I have multiple type of index on same field? Will it affect performance?
Example :
db.users.createIndex({"username":"text"})
db.users.createIndex({"username":1})
Yes, you can have different types of indexes on single field. You can create indexes of type e.g text, 2dsphere, hash
You can not create same index with sparse and unique options.
Every write operation is going to update a relevant index entry of all possible types in this case
The two index options are very different.
When you create a regular index on a string field it indexes the entire value in the string. Mostly useful for single word strings (like a username for logins) where you can match exactly.
A text index on the other hard will tokenize and stem the content of the field. So it will break the string into individual words or tokens, and will further reduce them to their stems so that variants of the same word will match ("talk" matching "talks", "talked" and "talking" for example, as "talk" is a stem of all three). Mostly useful for true text (sentences, paragraphs, etc).
Text Search
Text search supports the search of string content in documents of a collection. MongoDB provides the $text operator to perform text search in queries and in aggregation pipelines.
The text search process:
tokenizes and stems the search term(s) during both the index creation and the text command execution.
assigns a score to each document that contains the search term in the indexed fields. The score determines the relevance of a
document to a given search query.
The $text operator can search for words and phrases. The query matches on the complete stemmed words. For example, if a document field contains the word blueberry, a search on the term blue will not match the document. However, a search on either blueberry or blueberries will match.
$regex searches can be used with regular indexes on string fields, to provide some pattern matching and wildcard search. Not a terribly effective user of indexes but it will use indexes where it can:
If an index exists for the field, then MongoDB matches the regular expression against the values in the index, which can be faster than a collection scan. Further optimization can occur if the regular expression is a “prefix expression”, which means that all potential matches start with the same string. This allows MongoDB to construct a “range” from that prefix and only match against those values from the index that fall within that range.
http://docs.mongodb.org/manual/core/index-text/
http://docs.mongodb.org/manual/reference/operator/query/regex/

In Algolia, how do you construct records to allow for alphabetical sorting of query results?

As far as I know, you can only sort on numeric fields in Algolia, so how do you efficiently set up your records to allow for results to be returned alphabetically based on a specific string field?
For example, let's say in each record in an index you have a field called "title" that contains an arbitrary string value. How would you create a sibling field called "title_sort" that contains a number that allows for the the results to be sorted such that the records come out in alphabetical order by "title"? Is there a particularly well-accepted algorithm for creating such a number from the string in "title"?
If you have a static dataset, then you can just sort your data and put an index on it. This works as long as sorting data every time you update your indices.
I'm also thinking that if you can deal with a partial sorting, meaning that you can accept orc < orb but you need or < os, then you could derive an can use base64 as our index. You can then sort it to as many characters as you have precision for. It's only a partial sorting, but it might be acceptable for your use case. You just need to map your base64 -> base10 mappings to accomodate the sorting.
Additionally, if you don't care about the difference between capital and lowercase letters, then you can do base26 -> base10. The more I think about this the more limited it is, but it might work for your use case.

What does the digit "1" mean when creating indexes in mongodb

I am new to mongodb and want to make indexes for a specific collection. I have seen people use a digit "1" in front of the field name when they want to create an index. for example:
db.users.ensureIndex({user_name: 1})
now I want to know what does this digit mean and is it necessary to use it?
It's the type of index. MongoDB supports different kinds of indexes. However, only the first two indexes can be combined to a compound index.
1: Ascending binary-tree index.
-1: Descending binary-tree index. Very similar to the default index but the difference can matter for the behavior of compound indexes.
"hashed": A hashtable index. Very fast for lookup by exact value, especially in very large collections. But not usable for inexact queries ($gt, $regex or similar).
"text": A text index designed for searching for words in strings with natural language.
"2d": A geospatial index on a flat plane
"2dsphere": A geospatial index on a sphere
For more information, see the documentation of index types.
It defines the index type on that specefic field. For example the value of 1 creates an index with ascending order, while the value -1 create the index with descending order.
For more information, see the Manual