How to search by different variations on Algolia? - algolia

Let's say i have records of people with names like:
[
{ name: "Joe Smith" },
{ name: "Mary Cage" },
{ name: "Jenn Blair" }
]
If i used MySQL, i'd easily do something like:
WHERE name LIKE %Smith% OR name LIKE %Blair%
That will return two records (1 for Joe Smith and 1 for Jenn Blair).
How do I do the same with Algolia? I have tried queries like Smith OR Blair but they return nothing!

Algolia has no syntax for query conditions like this, by default all terms in query will be searched in your records.
However, you can do this with the optionalWords query parameter, which Algolia will use to remove words from the query:
optionalWords="Smith Blair"
query="Smith Blair"
This will return all records matching either "Smith" or "Blair".

Related

MongoDB sort string field with an internal order

I have a software written in PHP where I want to make some query and sort results.
I would like to sort the results by the field firstname.
But I would like that firstname is sorted (ASC sort) so if I have name: Mark Albert it must be before Beatrix because my query must consider Mark Albert like 'Albert Mark'.
How can I achieve this?
This is my basic query is:
db.users.find(
[
{ $sort : { firstname : 1 } }
]
)

Apply DISTINCT to MongoDB Results

I have a query as follow in `MongoDB.
db.Data.find(
{
FirstName:"John"
}
);
I get the result as follow
FirstName LastName Location
John Harvy Germany
John Doe France
John Baley Germany
John Kildy Italy
............................
I want to apply Distinct for location but when I apply based on distinct("Location", query"), I only receive the location field as the result and not the other fields (FirstName, LastName etc.) How can I use "Distinct" so that I can get other related fields to the distinct field too?
(In Short, I want to apply a find query first, and then apply distinct to it but I don't know how to combine the two as MongoDB runs them separately)
You can use aggregation for this
db.Data.aggregate([
{ $match : { FirstName:"John" } }, // Your Query
{ $group : {_id : "$Location" } } // Grouping the attribute you want as distinct
])

MongoDB Query Find multiple fields or documents properly

In my collection I got two fields, gender and country.
In the gender field they are all "female" and each of them are in different country.
I tried to query the collection:
return Meteor.users.find(
{
_id: {$ne: Meteor.userId()},
$or: [ { "country": "Australia" }, { "gender": "" } ]
}).fetch();
The result goes like this:
When set the gender to "null" or empty it gives me all the user who are in Australia.
But when I set gender to "female" and country to "Australia" it gives me all the female users from different countries which is supposed to be only female from Australia. It seems it ignores first argument which is the country.
Is there a way to have it more accurate? Please help thank you.
My Goal is:
To make the database query more accurately and bw able to adopt to the changes.
Example:
Going back to the issue above, when I added the "gender" on the search query, it should only look for female users whose country is Australia. Not all females from different countries.
Since you need to meet both the conditions female as well as country, it should be and
return Meteor.users.find({ _id: {$ne: Meteor.userId()},
$and: [{"country": "Australia"},
{"gender": "female"}]
}).fetch();
This might not be the perfect solution, but you can do something like this:
var filter = { };
filter._id = { $ne: Meteor.userId() };
if(Meteor.country()){
filter.country = Meteor.country();
};
if(Meteor.gender()){
filter.gender = Meteor.gender();
};
return Meteor.users.find(filter).fetch();
Also, since you don't know on what basis the query is to be performed, you shouldn't use operators like $and or $or
The query document that you prepared queries for all the users, where _id is not equal to Meteor.userId() AND country = AUSTRALIA or gender = FEMALE.
Also the solution that zangw suggested, there $and isn't required as all the criteria in the query document to the find method is implicitly ANDed.
Hope this helps.
I finally found out a solution on how to sort this out. It is a bit long code but it did the trick.
I scanned the data I got and remove null data, in my case above if gender is == to "" then ignore it else get its data if exist. I did it via loop.
Using array push I was able to insert object. Ex: If country is not null then:
variable.push('{"+objectPropertyName[i]+"'+':'+'"'+objectValue[i]+'"}');
The output of this looks like this:
["{"country":"Australia"}", "{"gender":"female"}"]
by parsing it to JSON then becomes an object.
Once all the objects necessary for the query is set the I can query the mongo through:
db.collection.find({"_id": {$ne: Meteor.userId()}, $and: **variable**}).fetch();
So far it works perfectly. :)

How to search for a specific pattern in MongoDB?

Im having trouble with my query in Meteor since I am not quite well versed with MongoDB.
This here is a sample collection with two documents.
Ducks:
[{
name: "duck1"
metadata: {
id: "id_1",
category: "samecategory"
}
},
{
name: "daffy"
metadata: {
id: "id_2",
category: "samecategory"
}
}]
I implemented a search functionality from atmosphere. What I want to achieve is that when I search for example: d the results will be both ducks. du will be only be duck1 and naturally da will only be daffy. Also so that they will be filtered by the same category.
"$and": [{"name": {}}, {"metadata.category": "samecategory"}]
Inside the name {} is where the search queries. It will only give me the result when the name is exact. I can't find in the mongo docs if it has contains like in Java.
The following query will return a subset of documents which names start with d and have metadata.category set to samecategory:
Ducks.find({"metadata.category": "samecategory", "name": /^d/});
The regular expression /^d/ is similar to LIKE 'd%'.

Querying and grouping in mongoDb?

Part 1:
I have (student) collection:
{
sname : "",
studentId: "123"
age: "",
gpa: "",
}
im trying to get only two keys from it :
{
sname : "",
studentId: "123"
}
so i need to eliminate age and gpa to have only name and studentId , how could i do that ?
Part2:
Then I have 'subject' collection :
{
subjectName : "Math"
studentId : "123"
teacherName: ""
}
I need to match/combine the previous keys (in part1) with the correct studentId so I will end up with something like this :
{
sname : "",
studentId: "123",
subjectName : "Math"
}
How can i do this and is that the right way to think to get the result? i tried to read about group and mapReduce but i didnt find a clear example.
To answer your first question, you can do this:
db.student.find({}, {"sname":1, "studentId":1});
The first {} in that is the limiting query, which in this case includes the entire collection. The second half specifies keys with a 1 or 0 depending on whether or not you want them back. Don't mix include and excludes in a single query though. Except for a couple special cases, mongo won't accept it.
Your second question is more difficult. What you're asking for is a join and mongo doesn't support that. There is no way to connect the two collections on studentId. You'll need to find all the students that you want, then use those studentIds to find all the matching subjects. Then you'll need to merge the two results in your own code. You can do this through whatever driver you're using, or you can do this in javascript in the shell itself, but either way, you'll have to merge them with your own code.
Edit:
Here's an example of how you could do this in the shell with the output going to a collection called "out".
db.student.find({}, {"sname":1, "studentId":1}).forEach(
function (st) {
db.subject.find({"studentId":st.studentId}, {"subjectName":1}).forEach(
function (sub) {
db.out.insert({"sname":st.sname, "studentId":st.studentId, "subjectName":sub.subjectName});
}
);
}
);
If this isn't data that changes all that often, you could just drop the "out" collection and repopulate it periodically with this shell script. Then your code could query directly from "out". If the data does change frequently, you'll want to do this merging in your code on the fly.
Another, and possibly better, option is to include the "subject" data in the "student" collection or vice versa. This will result in a more mongodb friendly structure. If you run into this joining problem frequently, mongo may not be the way to go and a relational database may be better suited to your needs.
Mongo's find() operator lets you include or exclude certain fields from the results
Check out Field Selection in the docs for more info. You could do either:
db.users.find({}, { 'sname': 1, 'studentId': 1 });
db.users.find({}, { 'age': 0, 'gpa': 0 });
For relating your student and subject together, you could either lookup which subjects a student has separately, like this:
db.subjects.find({ studentId: 123 });
Or embed subject data with each student, and retrieve it together with the student document:
{
sname : "Roland Browning",
studentId: "123"
age: 14,
gpa: "B",
subjects: [ { name : "French", teacher: "Mr Bronson" }, ... ]
}