- The Book of Dojo
- Quick Installation
- Hello World
- Debugging Tutorial
- Introduction
- Part 1: Life With Dojo
- Part 2: Dijit
- Part 3: JavaScript With Dojo and Dijit
- Part 4: Testing, Tuning and Debugging
- Part 5: DojoX
- The Dojo Book, 0.4
Selecting Items
Submitted by dante on Sat, 05/12/2007 - 02:03.
There are many times when you might not want an entire item list. Though you could fetch the entire list, and loop through to select elements, dojo.data's API definition has facilities to do the tough work for you.
Selecting subsets of items requires a query. A query is a JavaScript object that has attributes which look a lot like the attributes of the data store. It's a kind of query-by-example. So for our pantry, selecting the items from the Spice aisle involves this query:
{ aisle: "Spice" }
Each type of data store can have its own query syntax. With JsomItemStore, you can use wildcards: * to mean any characters. and ? to mean one character. This notation will be familiar to you if you've worked with Perl, Java, UNIX shell regular expressions, or even old BATCH scripts. And in general, the dojo.data community would highly recommend that all stores try to follow this method of specifying the query for consistency. Even datastores that are backed by an SQL database should be able to handle such character matching, because * maps to %, and ? maps to _ in SQL syntax.
The following query will pick up items in the Condiments aisle:
{ aisle: "Condiment*" }
Multiple attributes assume an "and" between the terms. So a query like the following one will match spices with the word pepper inside them, but not "green peppers" in the vegetable aisle:
{ name: "*pepper*", aisle: "Spices" }
Once we have constructed the query, we pass it to fetch()
along with the other parameters as shown in the following example:
Finally, it's important to note that searches are case-sensitive by default. If you want to make a case-insensitive query, just add the ignoreCase
option to the queryOptions
object as shown in the following example:
itemStore .fetch({ queryOptions: {ignoreCase: true}, query: { name: "*pepper*", aisle: "Spices" }, onComplete: ... });
This example will match both "Black Pepper" and "white pepper."
In general, any option that would affect the behavior of a query, such as making it case insensitive or doing a deep scan where it scans a hierarchy of items instead of just the top level items (the deep:true
option), in a store belongs in the queryOptions
argument.
Why isn't it just SQL for a query?
The simple and short answer to this question is that not all datastores are backed directly by a database that handles SQL. An immediate example is ItemFileReadStore, which just uses a structured JSON list for its data. Other examples would be datastores that wrap on top of services like Flickr and Delicious, because neither of those take SQL as the syntax for their services. Therefore, the dojo.data API defines basic guidelines and syntax stores that can be easily mapped to a service (for example, attribute names can map directly to parameters in a query string). The same is true for an SQL backed datastore. The attributes become substitutions in a prepared statement that the stores use (when they pass back the query to the server) and a simple common pattern matching syntax, the * and ?, which also map easily across a wide variety of datasource query syntax.
- Printer-friendly version
- Login or register to post comments
- Unsubscribe post
there isn't an OR
If you read the source code in 0.9M2 for data/JsonItemStore.js , you'll see that the fetch command is very simplistic and doesn't do "OR". Specifically:
...
items = [];
for(var i = 0; i < arrayOfAllItems.length; ++i){
var match = true;
var candidateItem = arrayOfAllItems[i];
for(var key in requestArgs.query) {
var value = requestArgs.query[key];
if (!self._containsValue(candidateItem, key, value, requestArgs.queryIgnoreCase)){
match = false;
}
}
if(match){
items.push(candidateItem);
}
}
findCallback(items, requestArgs);
}
This is a strict AND type of search. If any of the passed conditions fails the call to _containsValue, then match will be false (I've no clue why the search doesn't also short circuit there, but I guess that optimization hasn't been done yet).
Actually, I would respectfully suggest the developers look at the perl module SQL::Abstract, both for implementation details and a grammar for specifying complex queries. (see http://search.cpan.org/~nwiger/SQL-Abstract-1.22/lib/SQL/Abstract.pm#WHERE_CLAUSES ) SQL::Abstract of course just has to generate sql, not do the actual searching.
Correction?
I assume JsomItemStore is referring to the JSON ItemFile*Store drivers?