DateTime comparison using path range index - marklogic-10

I don't know whether it is doable or not but still I want to ask this question,
Lets say there are two xml documents in database as below,
URI - /item/A
<test>
<itemName>A</itemName>
<dateTime>2021-08-18T17:16:25</dateTime>
</employee>
URI - /item/B
<test>
<itemName>B</itemName>
<dateTime>2021-08-18T17:16:25.123</dateTime>
</employee>
I am getting value for xpath /test/dateTime like 2021-08-18T17:16:25(without milliseconds) from UI and based on this value I want to perform search to get all the documents where value of /test/dateTime equal to 2021-08-18T17:16:25 and I am expecting both the document(by ignoring milliseconds from doc /item/B) as result.
Path range index is also there for xpath /test/dateTime.
Update
I tried below query but it is returning only one document /item/A because it matches exact value on this document, but my requirement is to get both the document by ignoring milliseconds from second value, 2021-08-18T17:16:25.123
cts:search(doc(), cts:and-query((cts:path-range-query("/test/dateTime", "=", "2021-08-18T17:16:25"))), ("unfiltered"))

Related

Find documents with a certain field value only when another field value is a given string

I'm using this php package to make queries - https://github.com/jenssegers/laravel-mongodb
The situation is, there are two fields, user_id and post_status among others. I want to retrieve all the documents in that collection, but when post_status field value is draft, that should be retrieved only when user_id is a given string. The idea is, only logged in user finds their drafted posts among other posts.
I'm having hard time finding any solution for this problem. The app is still not in production. If I should store data is some different manner, that is an option as well.
Find documents with a certain field value only when another field value is a given string
The question your are framing is simply convert into a and query, how let's see it
when another field value is a given string
This means that you have some result sets and you need to filter out when user_id match with some string. i.e some result sets and user_id = <id>
Now consider the first part of the sentence Find documents with a certain field value
This means you are filtering the records with some values i.e "status" = "draft" and whatever result will come and want again to filter on the basis of user_id = <id>
So finally you will end-up with below query:
db.collectionName.find({"status":"draft", "user_id": "5c618615903aaa496d129d90"})
Hope this explanation will help you out or you can rephrase your question I will try to modify by ans.

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.

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.

CouchDB filtering on key array

Given a CouchDb view that emits like this:
emit([doc.name, doc.date], doc)
How to filter on multiple doc.name values? Below doesn't seem to work.
keys=[["name1",{}],["name2",{}],["name3",{}]]
When you specify the keys parameter, you are specifying an exact match. Assuming you want a range query (every document with name="name1" no matter the date) then you need to query with a startkey and an endkey:
?startkey=["name1", ""]&endkey=["name1", {}]
And will have to repeat the query for each name.

How to get only documents which have one field not empty

I'm trying to do create a query to exclude all documents which have an empty/null value in one specific field.
What is the query syntax or the programmatic way to do this?
You can use a required range query, which is open at both sides, like:
+field:[* TO *]
That is probably adequate, assuming that the documents to exclude have no value in the index.
If some form of default value appears, you would have to exclude that value as well, like:
+field:[* TO *] -field:NULL