MongoDB sort order on timestamp / ISODate fields - mongodb

If there is a MongoDB collection that contains documents with field foo with both integer timestamps and ISODate objects, what will the resulting order of a sorted query be?
Will one of the objects come before the other, or will they be compared and interleaved?
The reason I ask is because this is true in Javascript (see below), but I'm wondering what will happen in MongoDB's underlying implementation.
> new Date(400) <= 401
true
> new Date(401) <= 400
false

MongoDB does type checking and conversion for certain comparison and not for all of them. I would suggest looking further in the documentation at http://docs.mongodb.org/manual/reference/method/cursor.sort/#behaviors to see how the sort behaves in ordering when the types are different.

Related

How to set indexes correctly Firestore Java

I have posts collection and I want to take all the posts that its "start" field is greater that current time and user_id not equal to "1".
Query query = firebaseFirestore
.collection("posts")
.whereNotEqualTo("user_id", "1")
.whereGreaterThan("start", Timestamp.now());
I added index like on a screenshot, but still I get an error that I can’t use double condition.
What is wrong?index screenshot
An index won't help you here. The problem is that Firestore doesn't support the query you're trying to perform. Please review the documentation on query limitations to better understand:
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.
Your query is using a range filter and an inequality filter on different fields, which is not supported.

collection traversal order with mongoose methods like findOne() or findOneAndRemove()

How do mongoose methods like findOne() or findOneAndRemove() traverse a collection ? which object will this kind of methods return ? the oldest entry ? the first object from left to right in the collection ? do these methods sort collections by object id in ascending order during their execution ? or will it return a random object falling under the specified condition ? the Mongoose API Documentation just says "finds one document", it's probably obvious but it is not to me, hence this question ;)
[EDIT]
findOneAndRemove() documentation >>>
https://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove
simply states ("Finds a matching document")
findOne() documentation >>>
https://mongoosejs.com/docs/api.html#model_Model.findOne
(simply states "Finds one document")
How can I be sure which document will be found by these methods if I have, lets say, two books in a books collection that have the same value under a "name" property ?
This question occured to me while running tests using mocha during my learning of MongoDB >>>
https://github.com/yactouat/JSNotions/blob/master/learningMongoDBMongoose/test/delete_test.js
Most driver functions correspond to Mongo DB's methods.
If you Google it a bit, you can find all Mongo shell's functions and their documentation.
For example, according to: findOne documentation on Mongo DB's site:
Returns one document that satisfies the specified query criteria on
the collection or view. If multiple documents satisfy the query, this
method returns the first document according to the natural order which
reflects the order of documents on the disk. In capped collections,
natural order is the same as insertion order. If no document satisfies
the query, the method returns null.

Firestore order by time but sort by ID

I have been trying to figure out a way to query a list of documents where I have a range filter on one field and order by another field which of course isn't possible, see my other question: Order by timestamp with range filter on different field Swift Firestore
But is it possible to save documents with the timestamp as id and then it would sort by default? Or maybe hardcode an ID, then retrieve the last created document id and increase id by one for the next post to be uploaded?
This shows how the documents is ordered in the collection
Any ideas how to store documents so they are ordered by created at in the collection?
It will order by document ID (ascending) by default in Swift.
You can use .order(by: '__id__') but the better/documented way is with FieldPath documentID() I don't really know Swift but I assume that it's something like...
.order(by: FirebaseFirestore.FieldPath.documentID())
JavaScript too has an internal variable which simply returns __id__.
.orderBy(firebase.firestore.FieldPath.documentId())
Interestingly enough __name__ also works, but that sorts the whole path, including the collection name (and also the id of course).
If I correctly understood your need, by doing the following you should get the correct order:
For each document, add a specific field of type number, called for example sortNbr and assign as value a timestamp you calculate (e.g. the epoch time, see Get Unix Epoch Time in Swift)
Then build a query sorted on this field value, like:
let docRef = db.collection("xxxx")
docRef.order(by: "sortNbr")
See the doc here: https://firebase.google.com/docs/firestore/query-data/order-limit-data
Yes, you can do this.
By default, a query retrieves all documents that satisfy the query in
ascending order by document ID.
See the docs here: https://firebase.google.com/docs/firestore/query-data/order-limit-data
So if you find a way to use a timestamp or other primary key value where the ascending lexicographical ordering is what you want, you can filter by any fields and still have the results sorted by the primary key, ascending.
Be careful to zero-pad your numbers to the maximum precision if using a numeric key like seconds since epoch or an integer sequence. 10 is lexicographical less than 2, but 10 is greater than 02.
Using ISO formatted YYYY-mm-ddTHH:MM:SS date-time strings would work, because they sort naturally in ascending order.
The order of the documents shown in the Firebase console is mostly irrelevant to the functioning of your code that uses Firestore. The console is just for browsing data, and that sorting scheme makes it relatively intuitive to find a document you might be looking for, if you know its ID. You can't change this sort order in the console.
Your code is obviously going to have other requirements, and those requirements should be coded into your queries, without regarding any sort order you see in the dashboard. If you want time-based ordering of your documents, you'll have to store some sort of timestamp field in the document, and use that for ordering. I don't recommend using the timestamp as the ID of a document, as that could cause problems for you in the future.

Distinguish array from single value in a document

I have two type of documents in a mongodb collection:
one where key sessions has a simple value:
{"sessions": NumberLong("10000000000001")}
one where key sessions has an array of values.
{"sessions": [NumberLong("10000000000001")]}
Is there any way to retrieve all documents from the second category, ie. only documents whose value is an arary and not a simple value?
You can use this kind of query for that:
db.collectionName.find( { $where : "Array.isArray(this.sessions)" } );
but you'd better convert all the records to one type to keep the things consistent.
This code can be simple like this:
db.c.find({sessions:{$gte:[]}});
Explanation:
Because you only want to retrieve documents whose sessions data type is array, and by the feature of $gte (if data types are different between tow operands, it returns false; Double, Integer32, Integer64 are considered as same data type.), giving an empty array as the opposite operand will help to retrieve all results by required.
Also , $gt, $lt, $lte for standard query (attention: different behaviors to operaors with same name in expression of aggregation pipeline) have the same feature. I proved this by practice on MongoDB V2.4.8, V2.6.4.

Solr: Query for documents whose from-to date range contains the user input

I would like to store and query documents that contain a from-to date range, where the range represents an interval when the document has been valid.
Typical use cases in lucene/solr documentation address the opposite problem: Querying for documents that contain a single timestamp and this timestamp is contained in a date range provided as query parameter. (createdate:[1976-03-06T23:59:59.999Z TO *])
I want to use the edismax parser.
I have found the ms() function, which seems to me to be designed for boosting score only, not to eliminate non-matching results entirely.
I have found the article Spatial Search Tricks for People Who Don't Have Spatial Data, where the problem described by me is said to be Easy... (Find People Alive On May 25, 1977).
Is there any simpler way to express something like
date_from_query:[valid_from_field TO valid_to_field] than using the spacial approach?
The most direct approach is to create the bounds yourself:
valid_from_field:[* TO date_from_query] AND valid_to_field:[date_from_query TO *]
.. which would give you documents where the valid_from_field is earlier than the date you're querying, and the valid_to_field is later than the date you're querying, in effect, extracting the interval contained between valid_from_field and valid_to_field. This assumes that neither field is multi valued.
I'd probably add it as a filter query, since you don't need any scoring from it, and you probably want to allow other search queries at the same time.