Using mongojs and node.js, how to find documents using multiple attributes as criteria - javascript

I am trying to use the find method to return documents that meet multiple criteria like so:
db.issues.find({ 'title.name': name, 'title.year': year, 'title.publisher': publisher }, function(err, issues) { ...
I get an empty array back as a result.
If I try the same query directly in the mongodb console, I get the results back as expected.
In mongojs, I am able to retrieve results if I only supply one attribute, like so:
db.issues.find({ 'title.name': name }, function(err, issues) { ...
So, how do I perform a search using multiple attributes? Do I need to use a different method?
UPDATED 2/2/2014 7:56
The issue schema is as follows:
{
title: { name: 'Some title name', year: 1999, publisher: 'Some publisher' },
number: "122",
variant: null,
print: "1",
year: "1999",
certification: { type: "Some certification", grade: 10 },
url: "http://www.someurl.com",
sales: []
}

There is no difference in how mongojs handles queries as it's intention is to mimic ( somewhat ) the behavior of the mongo shell.
Are you sure your criteria actually returns something? As it stands you possibly have an issue there. If you still cannot diagnose this, post up the result you expect to get and some of your schema as an edit. Don't forget to check your var's that numbers aren't strings and vice versa.

Related

How to return available filters along with search query in elastic search

Basically im pretty new to elastic search and need some help in querying. Also let me know if i need to make any changes to my MongoDB Schema
I want to know how do i search in elastic search which would give me available products based on query and filters available to filter
something like
{
products: [{...}, {...}, ...],
filters: [ ... ]
}
product Schema is
{
title: "...",
description: "...",
categoryId: ObjectId
variants: [ variant1ID, variant2ID ],
... other miscellaneous stuff
}
Variant Schema is
{
product : objectId,
image: ..,
price: ...,
attributes:[
"SIZE-XL", // note: these are facetId , i can popuplate these to {name:"SIZE", value:"XL"}
"COLOR-BLUE",
....and so on
]
}
First i taught to retrive filters based on category, because each category has a fixed number of facets , then i realiased , search query doesnt really have to be specific to category,
Also i am thinking to store product in elastic in below format
{
productId: "...",
title:"..",
description: "...",
categoryId: "....",
image: "..",
variantId:"..."
price:"..",
attributes: [
{
name:"SIZE",
value:"XL",
},
{
name:"COLOR",
value:"BLUE",
}
.
.
.
]
}
basically storing each variant as seperately with its product title and description, So searching is fast and easier
You are right. In Elasticsearch you want to avoid using populate/joins and you look for flattening/de-normalizing your data.
You can read this article to have a better idea about modeling variants:
https://www.elastic.co/blog/how-to-create-a-document-schema-for-product-variants-and-skus-for-your-ecommerce-search-experience
You can create a query that returns facets of every any you need, as long as a keyword type of that field exists (by default it does).
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html
Then you can run a filter query:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-filter-context.html#filter-context
You want to use a "terms" query inside your filters because in most cases filters are exact matches (a checkbox in the UI) so this is the most efficient way to do it:
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html

Looking for Active Model Serializer like nested, associative output for Sequelize

Please forgive me if my research was inadequate. I've been reading the docs and searching this site to no avail for over an hour and I could really use some expert help.
With Rails, I can use Active Model Serializer to send data associated with the set queried. For example, let us say that I have Users, and Users have many Posts. Let us say that I want output that looks like this:
[
- {
id: 1,
username: "Matz",
posts: [
- {
id: 35,
title: "Hello world",
content_body: "This is the content of my post."
},
-{
id: 98,
title: "Foo Bar",
content_body: "This is the content of my other post."
}]},
]
Using Active Model Serializer this would be trivial. What I'm hoping is to get similar output using Sequelize.
My associations are working fine, and I am able to do for instance this:
return db.Users.findByPk(user_id)
.then(user => user.getPosts())
.then(posts => res.send(posts))
* edited to add *
One problem is that what I would really like to do is put the include inside of the user.getPosts(), for example.
What I need is the get the Posts belonging to a User, then get the Tag to which those Posts belong.
Thanks so much for any help. I am trying to avoid too many fetch requests.
Include within .getPosts does work. I had not understood the docs entirely.
Because I imported the models as so in my app.js:
const db = require('./models');
I needed to write the following:
return db.Users.findByPk(user_id)
.then(user => user.getPosts({
include: [{
model: db.Tags
}]
}))
.then(posts => res.send(posts))

Firebase database: how to get first record of each list

I have a nested firebase database with a structure like this:
posts: {
0: {
title: "...",
content: '...',
comments: [{
by: "someone"
}, {
by: "anotherone"
}]
},
1: {
...
}
}
Now I want to get the first comments on each post so I tried
firebase.database().ref('/posts/{postId}/comments/0').once('value',function(snapshot){
snapshot.forEach(function(child){ console.log(child.val());});
})
But don't know why the only thing I got in the console is false. So are there anyone knows what's wrong or is it impossible to query like that?
The Firebase Database SDKs will also read entire nodes. It is not possible to retrieve a subset of a node's data or to get just the keys.
To get the first comment of each post, you must know the key of each post already. Since you can't read just the keys of the posts, this means that you must read all data to get just the first comment of each post:
firebase.database().ref('/posts').once('value',function(snapshot){
snapshot.forEach(function(child){
console.log(child.val().comments[0]);
});
})
While this gives the result you need, it is quite wasteful in bandwidth: the client is ready way more data than you need. As usual in NoSQL databases, a better solution may require you to change your data model to fit your use-case. For example: consider storing the latest comment for each post in a separate top-level list:
latest-comments: {
0: {
by: "someone"
},
1: {
...
}
}
You will need to update this list (in addition to your original comments list) whenever a new comment is posted. But in return, reading the latest comment for each post is now very cheap.

I am unable to retrieve data from my mongodb collection and show it to my html page [duplicate]

I have a publication that should return me all users matching an _id array. here it the query:
Meteor.users.find({
'_id': { $in: myArray}},{
'profile.name':1,
'profile.description':1,
'profile.picture':1,
'profile.website':1,
'profile.country':1}
);
When I run it in Robomongo (the mongo browser), it works. But my publication only returns undefined. when I console.log(myArray); in the publication, I get something like this ['FZ78Pr82JPz66Gc3p']. This is what I paste in my working Robomongo query.
Alternative question: how can I have a better feedback(log) from the Collection.find() result?
It looks like you are trying to specify fields in your find, which you can do like this:
var options = {
fields: {
'profile.name': 1,
'profile.description': 1,
'profile.picture': 1,
'profile.website': 1,
'profile.country': 1
}
};
Meteor.users.find({_id: {$in: myArray}}, options);
However, if this is being used in a publish function, I strongly recommend using only top-level fields like so:
Meteor.users.find({_id: {$in: myArray}}, {fields: {profile: 1}});
For more details on why, please see this question.
For your second question, you can view the documents returned by a cursor by calling fetch on it. For example:
console.log(Posts.find({_id: {$in: postIds}}).fetch());

fetchRelated not fetching related

Been trying to get this up and running for a while now.
Basically i have a rest api as backend that returns json, all fine.
The problem i have is with backbone-relational. I'm sure i've just got something
wrong but i've been searching the nets for a while and couldn't find anything to help.
I'm trying to get a has many relationship between the model "Profession" and "Weapon".
Here's my code for that:
Profession = Backbone.RelationalModel.extend({
urlRoot: '../api/professions',
relations: [{
type: Backbone.HasMany,
key: 'weapons',
relatedModel: 'Weapon',
collectionType: 'Weapons',
reverseRelation: {
key: 'profession',
includeInJSON: 'id',
keySource: 'profession_id'
}
}]
});
Weapon = Backbone.RelationalModel.extend({
urlRoot: '../api/weapons'
});
Weapons = Backbone.Collection.extend({
model: Weapon,
url: function(models){
return '../api/weapons';
}
});
And a call to those api endpoints returns:
{name: "Profession1", id: 1}
[{name: "Weapon1", profession_id: 1}, {name: "Weapon2", profession_id: 1}]
So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')
So, if i understand correctly a profession.fetchRelated('weapons') should send an httprequest to the url for the weapons collection and pull the object which have a profession_id of 1. But nothing happens when i run profession.fetchRelated('weapons')
This is not how I understand Backbone-relational to work - with the caveat that I'm working with an older version, and have not yet investigated the latest versions.
From my understanding, Backbone-relational wants data that looks different from your API responses.
I think that Backbone-relational wants references to nested models in the parent model response, either fully nested:
{
name: "Profession1",
id: 1,
weapons: [
{name: "Weapon1", profession_id: 1},
{name: "Weapon2", profession_id: 1}
]
}
In which case, it will fully populate the nested models.
Or, as references:
{
name: "Profession1",
id: 1,
weapons: ['weapon1','weapon2']
}
In which case Backbone-relational will stash the related keys internally, but present an empty collection. You would then use fetchRelated to fetch the full data for the related models:
assassin.fetchRelated('weapons')
Which make a request for weapons with id 'weapon1' and 'weapon2', either as individual requests, or if your API accepts a set request, a single request, expecting a response something like:
{id: 'weapon1', name: "Weapon1", profession_id: 1}
I don't, off the top of my head, know if there's a quick, built-in way to work with your API responses, other then to write a custom function.
To add to what Edward wrote, here's how you can get fetchRelated to work. First, as Edward claimed, fetchRelated will return nothing if your API already nests the data in the JSON response. So, if in Django-Tastypie you have your resource set up to use full=True:
movies = fields.ToManyField('movie.api.MovieResource', 'user', full=True)
then something like,
myuser.fetchRelated("movies")
will return nothing because the related data will already be included in the JSON response. But where fetch related is particularly useful is when you are attempting to do some lazy loading. So, if you have full=False in your Django-Tastypie field, and your JSON response only includes the id's and resource URI to that entry, you can use fetchRelated to actually populate that data.
myuser = new User({id: 1})
myuser.fetch()
myuser.fetchRelated("movies")
And now you have access to the related movies collection. If you're also using the Tastypie-Backbone plugin, you don't need to worry about constructing a special URL return statement in the Collection. It does it all for you using the tastypie select syntax of /2;3;7

Categories