I have already searched in other questions for a solution, but didn't find it.
So, my problem is the following:
I have a page where the user can mount an expression. For example, if they want some professors with course 1 and course 2 then, they create an expression like this:
(course 1 AND course 2) in the page.
But when I use EF, if I put the "AND", I get no professor... if I change to "OR" I get some professors with 1 or 2 and maybe one of then have two courses.
I need the professors who have always the two courses (course 1 AND course 2)
How can I accomplish this?
(If my explanation get too confusing, let me know, I'll try in a other way!)
I tried to understand your explanation, Try something as following and let usknow if is the logic you are looking for? or you want something other result.
from x in db.professors.Where(x => x. professorId == professorId && (x.courseid == 'course1' && x.ukat == 'course2'))
Maybe:
var result = db.Professors.Where(p =>
p.Cursos.Count(c => searchedCourses.Contains(c.CourseId)) == searchedCourses.Count());
This way you get all the professors, filter their courses to match that in the specified search, and get only the professors with the same amount of filtered courses and the searched ones.
Related
This is very obvious but tricky question. I could not find its answer on web or simply i am missing keywords that could find its answer.
Let's say we have many conditions based on which we want to filter data. These conditions are in multiple blocks. How to write them so that they work as AND clause but not OR providing they participate only in certain condition.
var query = _entities.AsQueryable();
if (model.CityId != default)
{
query = query.Where(x => x.CityId == model.CityId);
}
if (!string.IsNullOrWhiteSpace(model.PostalCode))
{
query = query.Where(x => x.Proppostcode == model.PostalCode);
}
if (!string.IsNullOrWhiteSpace(model.AirportCode))
{
query = query.Where(x => x.AirportCode == model.AirportCode);
}
Let me know guys if this question need more details. Thank you!
am I missing keywords that could find its answer?
Yes, This missing keyword is Dynamic Expression or Dynamic Query. If you follow these keywords you'll find a lot of solutions to your problem.
As this tutorial said:
Dynamic Query allows you to perform dynamic where clause, select, order by, with string expression at runtime.
you can follow below links, too:
CodeProject
Microsoft
good luck.
I have two Seq[_]es in my Play application.
Now I want to make a diff of those and get as a result an Seq with all items which are not in the other one.
I tried to use .filter() but I don't know if thats a good way
How can I achieve this?
thanks in advance
Update ... PseudoCode Example
I have two Seq[]
1.) Seq[CarsInStock]
Attributes[ID, Brand, Color]
[{1,Porsche,Red},{3,Mercedes,Blue}]
2.) Seq[CarsAfterSale]
Attributes[ID, Brand, Color,Doors,Windows]
[{1,Porsche,Red,4,10}]
Now I wan't to make a diff between the two seq[]. As result I want to get the Object {3,Mercedes,Blue}] because it is in stock, but after sales I have to know which ones I have to remove from stock.
I want to recognize the difference by the ID of the elements
You can simply filter out all cars whose id exist in the other Seq.
stock.filterNot(c => afterSale.exists(_.id == c.id))
Unless you expect the second Seq to be short, you can probably optimize it by creating a Set of ids:
val afterSaleIds = afterSale.iterator.map(_.id).toSet
stock.filterNot(c => afterSaleIds.contains(c.id))
Is it possible with doctrine mongodb createquerybuilder() to add multiple references to a document ?
Here's an example of what I want to do:
I have 2 collections : Users and Movements in a 1:n relation so a User has multiple movements and a movement refers to a user.
To get the movements from a user, I can do
$user->getMovements();
I can also call doctrine createQueryBuilder like this:
$query->createQueryBuilder('Movement');
$query->field('user')->references($user);
Both give me the expected results. But what if I want to fetch the movement of 2 or 3 users in one query ?
Is it possible to do something like (which I tried but did not work)
$q->field('user')->references($user1);
$q->field('user')->references($user2);
// etc.
I stuck with that kind of query. Thanks for help !
Colzak.
Ok, So I found a solution that may not be the best one but it works.
Instead of doing
$q->field('user')->references($user);
You can do
$->field('user.$id')->equals(new \MongoId($user->getId());
So if you have an array of user, you can do something like
$userIds = array();
foreach ($users as $user) {
$userIds[] = new \MongdoId($user->getId());
}
And then the query:
$q->field('user.$id')->in($userIds);
Hope it'll help someone !
How does one use Firebase to do basic auto-completion/text preview?
For example, imagine a blog backed by Firebase where the blogger can tag posts with tags. As the blogger is tagging a new post, it would be helpful if they could see all currently-existing tags that matched the first few keystrokes they've entered. So if "blog," "black," "blazing saddles," and "bulldogs" were tags, if the user types "bl" they get the first three but not "bulldogs."
My initial thought was that we could set the tag with the priority of the tag, and use startAt, such that our query would look something like:
fb.child('tags').startAt('bl').limitToFirst(5).once('value', function(snap) {
console.log(snap.val())
});
But this would also return "bulldog" as one of the results (not the end of the world, but not the best either). Using startAt('bl').endAt('bl') returns no results. Is there another way to accomplish this?
(I know that one option is that this is something we could use a search server, like ElasticSearch, for -- see https://www.firebase.com/blog/2014-01-02-queries-part-two.html -- but I'd love to keep as much in Firebase as possible.)
Edit
As Kato suggested, here's a concrete example. We have 20,000 users, with their names stored as such:
/users/$userId/name
Oftentimes, users will be looking up another user by name. As a user is looking up their buddy, we'd like a drop-down to populate a list of users whose names start with the letters that the searcher has inputted. So if I typed in "Ja" I would expect to see "Jake Heller," "jake gyllenhaal," "Jack Donaghy," etc. in the drop-down.
I know this is an old topic, but it's still relevant. Based on Neil's answer above, you more easily search doing the following:
fb.child('tags').startAt(queryString).endAt(queryString + '\uf8ff').limit(5)
See Firebase Retrieving Data.
The \uf8ff character used in the query above is a very high code point
in the Unicode range. Because it is after most regular characters in
Unicode, the query matches all values that start with queryString.
As inspired by Kato's comments -- one way to approach this problem is to set the priority to the field you want to search on for your autocomplete and use startAt(), limit(), and client-side filtering to return only the results that you want. You'll want to make sure that the priority and the search term is lower-cased, since Firebase is case-sensitive.
This is a crude example to demonstrate this using the Users example I laid out in the question:
For a search for "ja", assuming all users have their priority set to the lowercased version of the user's name:
fb.child('users').
startAt('ja'). // The user-inputted search
limitToFirst(20).
once('value', function(snap) {
for(key in snap.val()){
if(snap.val()[key].indexOf('ja') === 0) {
console.log(snap.val()[key];
}
}
});
This should only return the names that actually begin with "ja" (even if Firebase actually returns names alphabetically after "ja").
I choose to use limitToFirst(20) to keep the response size small and because, realistically, you'll never need more than 20 for the autocomplete drop-down. There are probably better ways to do the filtering, but this should at least demonstrate the concept.
Hope this helps someone! And it's quite possible the Firebase guys have a better answer.
(Note that this is very limited -- if someone searches for the last name, it won't return what they're looking for. Hence the "best" answer is probably to use a search backend with something like Kato's Flashlight.)
It strikes me that there's a much simpler and more elegant way of achieving this than client side filtering or hacking Elastic.
By converting the search key into its' Unicode value and storing that as the priority, you can search by startAt() and endAt() by incrementing the value by one.
var start = "ABA";
var pad = "AAAAAAAAAA";
start += pad.substring(0, pad.length - start.length);
var blob = new Blob([start]);
var reader = new FileReader();
reader.onload = function(e) {
var typedArray = new Uint8Array(e.target.result);
var array = Array.prototype.slice.call(typedArray);
var priority = parseInt(array.join(""));
console.log("Priority of", start, "is:", priority);
}
reader.readAsArrayBuffer(blob);
You can then limit your search priority to the key "ABB" by incrementing the last charCode by one and doing the same conversion:
var limit = String.fromCharCode(start.charCodeAt(start.length -1) +1);
limit = start.substring(0, start.length -1) +limit;
"ABA..." to "ABB..." ends up with priorities of:
Start: 65666565656565650000
End: 65666665656565650000
Simples!
Based on Jake and Matt's answer, updated version for sdk 3.1. '.limit' no longer works:
firebaseDb.ref('users')
.orderByChild('name')
.startAt(query)
.endAt(`${query}\uf8ff`)
.limitToFirst(5)
.on('child_added', (child) => {
console.log(
{
id: child.key,
name: child.val().name
}
)
})
I tried to grab the latest N records with a unique value (first_name).
So far:
#users = User.all(:limit => 5, :sort => [:created_at, :desc]).distinct(:first_name)
almost works..But ignores the limit and sort order
Also:
#users = User.limit(5).desc(:created_at).distinct(:first_name)
Ignores both 'limit' and 'desc'
#users = User.limit(5)
Works..
What am I doing wrong?
Any help would be greatly appreciated!
I played with this for a little while and this is the best I could come up with.
Good luck.
#users = User.desc(:created_at).reduce([]) do |arr, user|
unless arr.length == 5 || arr.detect{ |u| u.first_name == user.first_name }
arr << user
end
arr
end
Have you tried using a pagination gem such as amatsuda / kaminari and limiting the results using page().per()?
Both distinct and count ignore the limit command in Mongoid. With count you can pass true (i.e. User.limit(5).count(true)) to force it to pay attention to the scope. Unfortunately there is no such trick for distinct as far as I'm aware (see docs/source here).
If you want to just grab the first 5 first_name's you can do this (not distinct):
User.desc(:created_at).limit(5).map(&:first_name)
This will respect the limit, but still load 5 full objects from the database (then discard the rest of the object to give you full name). If you actually need to run distinct, you're better off heading toward an aggregation framework solution.
I haven't tested, but this seems to be what you're looking for: https://stackoverflow.com/a/17568267/127311
I played with some result I found this.
User.limit(2).count => 10 #but in array I found only two results
User.limit(2).to_a.count => 2
May be limit gives the correct result, but count query gives wrong result.