I have a MongoDB collection organized like the following document:
{ "_id" : ObjectId("55f699bb1638cf0f4ba139f1"), "code" : 169, "categories" : "Consulenti del lavoro", "listing" : "B", "macrocategory" : "Consulenti" }
I need to get an array of the macrocategory field, but it's assigned to multiple documents and I need only one occurence of each of them. I tried using distinct in my Eloquent query, but I can't use it as I don't know which is the return value.
My query now, which returns the macrocategories multiple times:
$macrocategories = Category::orderBy('macrocategory','asc')->get();
Thanks!
You suppose to use distinct when you want an entire row to be unique,when you want a specific column to be unique you should use GROUP BY
I guess the distinct would be the same as yours order by coulmn -
$macrocategories = Category::orderBy('macrocategory','asc')->groupBy('macrocategory')->get();
BTW if you have columns that you don't need you should use select and fetch only the columns you do.
Related
I want to create a new table based on this one:
that filters for Warehouse=2 and "drops" the columns "Price" and "Cost" like this:
I have managed to apply the filter in the first step using:
FILTER(oldtable;oldtable[Warehouse]=2)
and then in the next step cold create another table that only selects the required columns using:
newtable2=SELECTCOLUMNS("newtable1";"Articlename";...)
But I want to be able to combine these two functions and create the table straight away.
This is very simple, because in your first step, a table is returned which you can use directly in your second statement.
newTabel = SELECTCOLUMNS(FILTER(warehouse;warehouse[Warehouse]=2);"ArticleName";warehouse[Articlename];"AmountSold";warehouse[AmountSold];"WareHouse";warehouse[Warehouse])
If you want to keep the overview, you can also use variables and return:
newTabel =
var filteredTable = FILTER(warehouse;warehouse[Warehouse]=2)
return SELECTCOLUMNS(filteredTable;"ArticleName";warehouse[Articlename];"AmountSold";warehouse[AmountSold];"WareHouse";warehouse[Warehouse])
I have a model Form for table forms. There is a column called guid which can be null, or contain some sort of grouping random hash.
I need to select all forms that have column guid either null or unique in current search. In other words, for repeating guid values in current search I select only first occurence of every guid hash.
I tried:
$results = App\Form::where(... some where clauses .. ).groupBy('guid')
and it's almost ok, but for all rows, where guid == NULL it groups them and selects only one (and I need all of them).
How can I get the unique or null rows either by building proper SQL query or filtering the results in PHP?
Note: I need my $results to be an Illuminate\Database\Eloquent\Builder instance
EDIT:
I fount out that SQL version of query I need is:
SELECT * FROM `forms` WHERE .... GROUP BY IFNULL(guid, id)
What would be equivallent query for Laravel's database query builder?
UPDATE: Using DB::raw
App\Form::where(... conditions ...)
->groupBy(DB::raw("IFNULL('guid', 'id')"));
Or the another way could be:
You can also use whereNotNull, whereNull & at last merge both the collections using merge() like this:
First get the results where guid is grouped by (excluding null guid's here):
$unique_guid_without_null = App\Form::whereNotNull('guid')->groupBy('guid')->get();
Now, get the results where guid is null:
$all_guid_with_null = App\Form::whereNull('guid')->get();
and at last merge both the collections using merge() method:
$filtered_collection = $unique_guid_without_null->merge($all_guid_with_null);
Hope this helps!
For your edited question, you can use raw() as;
->groupBy(DB::raw("IFNULL('guid', 'id')"))
So your final query will be as:
$results = App\Form::where(... some where clauses .. )
->groupBy(DB::raw("IFNULL('guid', 'id')"));
By above query, your $results will be an instance of Illuminate\Database\Eloquent\Builder.
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
I'm using php API to query two sphinx indexes as below
$cl->Query("test","index1 index2");
and I'm getting the result from both of successfully but I can't differentiate which result is from which index. is there a way to tell the difference? or do I need to do 2 queries separately?
Set a unique attribute on each
source1 {
sql_query = SELECT id, 1 as index_id, ....
sql_attr_unit = index_id
}
source2 {
sql_query = SELECT id, 2 as index_id, ....
sql_attr_unit = index_id
}
Results will contain a 'index_id' attribute.
Almost the same if using RT indexes. just need to define a rt_attr_unit and then populate it appropriately when you inject data into the index.
The otherway, persumably you've already arranged for the ids in the two indexes to be non-overlapping (it wont work if have the same ids in both indexes) so can look a the ID to deduce the source index.
mysql function in Codeigniter I Use list_field() to return an array containing the field names. What does the equivalent in mongoDB to return an array which contains he field name?
This code below I use the list_field function
function GetField($execution) {
$query = $this->db->query($execution);
if ($query->num_rows() > 0) {
return $query->list_fields();
} else {
return array();
}
}
My goal is if there is input with complex queries, the column appears dynamically in accordance with the input query
So the point I want to create applications such as rockmongo & phpMyAdmin. So when we enter a query, the results matching the query which we enter. Well I still have not found a function that bson field of MongoDB appear dynamically according to the query given by user.
example the query like this below :
db.users.find({}, {a:1,b:1})
so the bson field that appears is a and b.
There is NO equivalent query in MongoDB. It is a schema-less database, which means that every document can have totally different set of fields.
The find method returns a cursor iterating which you will get a result which in turn depending on a driver may be a hash-table or a dictionary where its keys are the names of a document's attributes.
something like that:
{"name" : "John","age" : 30, "_id" : "497ce96f395f2f052a494fd4"}
so that "field names" would be "name","age","_id"
Please Note
Since Mongo is schema-less for each document in a query there may be different keys.