简体   繁体   中英

How to find documents in ArangoDB which have a certain date (range) in an array?

I am trying to find all documents within a collection that have events within a certain date range.

Simplified the document structure looks like this:

{
    "name": "Example document",
    "other": "property",
    "date_events": [
        {
            "start": "1963-10-12T00:00:00.000Z",
            "end": "1963-10-13T12:00:00.000Z"
        },
        {
            "start": "1970-04-20T00:00:00.000Z",
            "end": "1970-04-20T12:00:00.000Z"
        }
    ]
}

There are n documents, which all have the property date_events , which is an array of objects, containing n events, each event has start and end .

Now I want to find all documents which have events within a certain date range, eg. between 1970-04-10 and 1970-04-28 :

FOR doc IN api_documents
    FILTER (doc.date_events[*].start ANY >= "1970-04-10T00:00:00.000Z" &&
        doc.date_events[*].end ANY <= "1970-04-28T12:00:00.000Z")
    RETURN { _key: doc._key, _id: doc._id, events: doc.date_events[*] }

The problem is, that the above query is incorrect and the result contains also documents that have no matching events whatsoever, eg. this one:

{
    "name": "False positive",
    "other": "property",
    "date_events": [
        {
            "start": "1966-02-24T00:00:00.000Z",
            "end": "1966-02-24T12:00:00.000Z"
        },
        {
            "start": "1979-11-26T00:00:00.000Z",
            "end": "1979-11-30T12:00:00.000Z"
        },
        {
            "start": "1980-01-31T00:00:00.000Z",
            "end": "1980-01-31T12:00:00.000Z"
        }
    ]
}

I can get it to work when only filtering for one property, eg. start . But as soon as both start and end is in the query, all the queries that I was able to come up with, either produce zero results or false positives, which do not match the input date range.

Is the usage of the ANY operator incorrectly here when looking for two properties or what am I doing wrong?

Thank you.

Your current query returns every document that includes date_events that fit either criterion.

To make sure both criteria are matched by a single date_event , you can filter date_events in a sub-query and then filter for non empty results, something like this (untested, but should get you started):

FOR doc IN api_documents
    LET matches = (
        FOR de IN doc.date_events
            FILTER de.start >= "1970-04-10T00:00:00.000Z" &&
                   de.end <= "1970-04-28T12:00:00.000Z"
            RETURN 1
    )
    FILTER LENGTH(matches) > 0
    RETURN { _key: doc._key, _id: doc._id, events: doc.date_events }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM