How to specify ordering in rethinkdb between query using index - rethinkdb

I want to do something like the following:
r.db('mydb').table('tab').between(
['s', 0],
['s', 99999], {index: r.desc('s-t')})
but this is not a correct Rql query:
RqlCompileError: DESC may only be used as an argument to ORDERBY. in:
Can I safely use
r.db('mydb').table('tab').between(
['s', 0],
['s', 99999], {index: 's-t'}).orderBy({index: r.desc('s-t')})
Will it be executed optimally (using single read instead of reading all records and then sorting them?

Yes, if you chain a between command with an orderBy one (using the same index), it will be executed in an efficient way.

Related

How to write queries traversing n hops in GQLAlchemy?

I have a query that I would like to model using GQLAlchemy:
MATCH (n)-[2]->(c)
RETURN Count()
How can I do this?
You can do the following within GQLAlchemy to traverse using hops.
An alternative would be to use the current syntax and a small hack. This is how the following query could be implemented in the query builder:
MATCH ({name: 'United Kingdom'})<-[:LIVING_IN*1..2]-(n) RETURN n;
match().node(name="United Kingdom").from_(edge_label="LIVING_IN*1..2").node(variable="n").return_({"n", "n"}).execute()

Laravel / Eloquent - how to ORDER BY FIELD

I'm trying to sort my query results based on a series of slash-separated ids (from the URL, e.g. /10/25/1). I grab the URL segments and explode them to get an array with elements 10, 25, 1. Now, I want my SQL to be something like this:
ORDER BY FIELD(`products`.`id`, 10, 25, 1)
In Eloquent, I'm trying to do this:
->orderByRaw('FIELD(`products`.`id`, ?)', [implode(', ', $product_ids)])
But that outputs something like this:
ORDER BY FIELD(`products`.`id`, "10, 25, 1")
I could declare a variable, loop through my array, and build the string 10, 25, 1 and just use that variable in place of the ? -- however, I would not be getting the benefit of whatever Eloquent does to prevent SQL injection attacks.
Suggestions?
Each parameter needs to have its own placeholder.
You can implode placeholders and pass the array as a parameter:
$placeholders = implode(',', array_fill(0, count($product_ids), '?'));
->orderByRaw("FIELD(`products`.`id`, $placeholders)", $product_ids)

Remove quotes from MongoTemplate query with $in clause

I have mongoTemplate query with a combination of various criterias. In this query I need to select documents by a collection of Ids. So I use "in" method.
Here is my code:
Query query = new Query(Criteria.where("sizeId").is(sizeId));
query.addCriteria(Criteria.where("companyId").in(companyIds));
List<StatisticUnit> result = mongoTemplate.find(query, StatisticUnit.class);
"companyIds" is a List of Integer values.
I've got no result because MongoTemplate wraps $in operator arguments in qoutes so that Mongo consider them as Strings. Real query looks like this:
$in: ["5", "15"]
instead of
$in: [5, 15]
How to tell mongoTemplate not to ignore a type of collection values and not to wrap them in quotes in case of Integer? Thanks!
I solved this issue by myself. When I use HashSet instead of ArrayList everything goes ok. Hope this helps someone else.

How to use RethinkDB indices in the following scenario?

I'd like to use an index to select all documents that don't have a particular nested field set.
In my situation with the JS-api this works out to this:
r.table('sometable').filter(r.row('_state').hasFields("modifiedMakeRefs").not())
How would I use an index on the above? I.e.: filter doesn't support defining indices afaik?
You would write:
r.table('sometable').indexCreate('idx_name', function(row) {
return row('_state').hasFields("modifiedMakeRefs");
})
And then:
r.table('sometable').getAll(false, {index: 'idx_name'})

RethinkDB index for filter + orderby

Lets say a comments table has the following structure:
id | author | timestamp | body
I want to use index for efficiently execute the following query:
r.table('comments').getAll("me", {index: "author"}).orderBy('timestamp').run(conn, callback)
Is there other efficient method I can use?
It looks that currently index is not supported for a filtered result of a table. When creating an index for timestamp and adding it as a hint in orderBy('timestamp', {index: timestamp}) I'm getting the following error:
RqlRuntimeError: Indexed order_by can only be performed on a TABLE. in:
This can be accomplished with a compound index on the "author" and "timestamp" fields. You can create such an index like so:
r.table("comments").index_create("author_timestamp", lambda x: [x["author"], x["timestamp"]])
Then you can use it to perform the query like so:
r.table("comments")
.between(["me", r.minval], ["me", r.maxval]
.order_by(index="author_timestamp)
The between works like the get_all did in your original query because it gets only documents that have the author "me" and any timestamp. Then we do an order_by on the same index which orders by the timestamp(since all of the keys have the same author.) the key here is that you can only use one index per table access so we need to cram all this information in to the same index.
It's currently not possible chain a getAll with a orderBy using indexes twice.
Ordering with an index can be done only on a table right now.
NB: The command to orderBy with an index is orderBy({index: 'timestamp'}) (no need to repeat the key)
The answer by Joe Doliner was selected but it seems wrong to me.
First, in the between command, no indexer was specified. Therefore between will use primary index.
Second, the between return a selection
table.between(lowerKey, upperKey[, {index: 'id', leftBound: 'closed', rightBound: 'open'}]) → selection
and orderBy cannot run on selection with an index, only table can use index.
table.orderBy([key1...], {index: index_name}) → selection<stream>
selection.orderBy(key1, [key2...]) → selection<array>
sequence.orderBy(key1, [key2...]) → array
You want to create what's called a "compound index." After that, you can query it efficiently.
//create compound index
r.table('comments')
.indexCreate(
'author__timestamp', [r.row("author"), r.row("timestamp")]
)
//the query
r.table('comments')
.between(
['me', r.minval],
['me', r.maxval],
{index: 'author__timestamp'}
)
.orderBy({index: r.desc('author__timestamp')}) //or "r.asc"
.skip(0) //pagi
.limit(10) //nation!
I like using two underscores for compound indexes. It's just stylistic. Doesn't matter how you choose to name your compound index.
Reference: How to use getall with orderby in RethinkDB

Resources