Let’s start with the easy one, Yes, it’s arbitrary, but you can help making it a little meaningful by choosing according to what it get to work with. I tend to go with stuff like dv.pages().where( p => ...)
to denote that I’m working within the page context. And l
for list items, and t
for task item if my query has done something to change the context.
A contrived example:
```dataviewjs
const pages = dv.pages()
.where(p => p.file.name == "something") // Now we're in the _page_ context
.file // Pick out just the file, so we're in the _file_ context
.where( f => f.link == "something else")
.lists // Pick the lists out of the valid files, so _lists_ contexts
.where( l => l.text == "Finally... ")
```
Here I could’ve used the same or different letters/names in each case, but I opted to use a single letter denoting the context as I’ve selected it down the chaining. Hope this make sense.
This is a lot easier asked, then answered. Reason being that your examples are not just strings, but a mix of strings and dates. Whenever Dataview (or dataviewjs) sees something in the format of YYYY-MM
it converts that string into a date. See Data Types - Dataview
So when you are using just years, they’re not considered dates, but they remain dates.
Example showing string vs date
Load the following into a note, and study it, and see if you can fathom the difference.
start-date:: 1894
start-date:: 1895-01-11
start-date:: 1904
start-date:: 1904-01
## Display the values
```dataviewjs
function asString(date) {
if ( typeof(date) == "number" ) {
return date.toString()
} else if ( date instanceof DateTime ) {
return date.toFormat("yyyy-MM-dd")
} else {
return date.toString() // and hope for the best
}
}
const startDates = dv.current().start_date
startDates.forEach(d => {
dv.paragraph(`${ d } -- typeof: ${ typeof(d) }, DateTime?: - ${ d instanceof DateTime }, asString: ${ asString(d) }`)
})
```
The output should be something like this:
Notice how the second and the last, are showing as complete date- and timestamps, since they’re interpreted as dates. They’ve also got “true”, and typeof: object
, instead of “false” and typeof: number
.
So in order to be able to work with these, we need to change the fields into common ground, and that is what the asString()
function does. It converts any dates back into “YYYY-MM-DD” again, and tries to make a string out of anything else. (This function could surely be made nicer and better, and account potentially other variants to ensure that we always get as much as possible out of a string in the “YYYY-MM-DD” format as possible)
Another issue you’re facing is that you’ve named your field start-date
. This is legal, but unfortunate, as you need to change how to reference. Note how in my example I changed this into start_date
, which made it possible to do dv.current().start_date
. If using your variant, I would have to use dv.current()["start-date"]
(as I did in the next segment).
And finally, use startsWith()
to match
When we’ve assured our field is just text, we can use startsWith
to check the start of the text, or match()
to do regex matches, and all the other string matching functions of javascript. So to do the check in your question of something starting with 189
, we can do the following:
```dataviewjs
function asString(date) {
if ( typeof(date) == "number" ) {
return date?.toString()
} else if ( date instanceof DateTime ) {
return date?.toFormat("yyyy-MM-dd")
} else {
return date?.toString() // and hope for the best
}
}
const oldStuff = dv.pages('"/timeline_items"')
.where( p => asString(p["start-date"]).startsWith('189') )
.map( p => [ p.file.link, asString(p["start-date"]) ] )
dv.list(oldStuff)
```
And hopefully, that should work in your setting, as a similar query worked for mine to produce this list:

(Not exactly the same base data as in previous example, but the datestrings where the same)
An alternative approach
Doing all this stuff to ensure string handling is a little cumbersome, and might be a little confusing. Depending on your other needs, whether you need to actually use it as date sometime, it might be worth considering to enforce it as a string in all cases from the start.
This can be done doing: start_date:: "2023-02-01"
in your files. Then dataview wouldn’t treat as a date at all, and your query could be the much simpler variant of:
```dataviewjs
const oldStuff = dv.pages('"/timeline_items"')
.where( p => p.start_date.startsWith('189') )
.map( p => [p.file.link, p.start_date] )
dv.list(oldStuff)
```
And if you wanted some of them parsed as dates, you could still do date(p.start_date)
(if the year and month are present so it’s a valid date)