How to use second LIKE in typeorm find query? I try like below, but not work and always return empty array
return await this.conn.getRepository(Article).find({
where: {
body: Like(`%${query}%`),
//title: Like(`%${query}%`), //NOT WORK WITH SECOND
},
order: {
lastUpdate: 'DESC'
},
relations: ['author']
});
thanks for any help!
I have to make a lot assumptions about your data and use case.
I suspect that the problem you are having has to do with the boolean operation that gets generated by TypeORM for your where condition(s).
Based on the way you have specified your request the resulting boolean operation is an AND. This means it will only return TRUE if both body AND title contain the search string.
I suspect this is NOT what you intended. I am assuming that what you really want is for the where to return TRUE if body or title or both contain the search string.
If all my assumptions are all correct, then you should be able to get the result you want by changing your request to the following:
return await this.conn.getRepository(Article).find({
where: [
{body: Like(`%${query}%`)},
{title: Like(`%${query}%`)}
],
order: {
lastUpdate: 'DESC'
},
relations: ['author']
});
Using this form of the request should result in a where clause that use an OR operator between the two Like tests.
Related
This seems redundant, and forces me to hard-code the same string in two spots - or stick it in a variable that has to be passed around. Either way, if I specify the "as" of a relationship in my model, why do I have to call it later with the same "as" property when querying?
My relationship:
organization.hasMany(client, { as: "Clients", foreignKey: "organization_id" });
client.belongsTo(organization, { as: "AuthOrganization", foreignKey: "organization_id" });
Query:
let data = await client.findOne({
include: [{ model: organization, as: "AuthOrganization" }]
}, { raw: true });
If I omit the same "as" property, an error is thrown telling me to put it in there. I'm new to Sequelize, but it appears to be this way because "as" can be used to identify relationships where it's ambiguous. However, seems like a reasonable default would be the value you set in the model, no?
What I really want is this, when I write a query:
let data = await client.findOne({
include: organization
}, { raw: true });
I'm only doing this to avoid the automatic underscore in the mixin function names. I couldn't stomach the fugly "addAuth_organization" function name, and I couldn't find another way around this issue, either.
I'll take that as a "yes". 😆
Hello there, a quick MongoDB mixed with some Discord knowledge question:
So currently, I want a formation for my MongoDB Document similar to the following:
channels: {
utility:{
suggestions: String
},
logging: {
main: String,
channel: {
channelCreate: String,
channelDelete: String,
channelUpdate: String,
},
role: {
roleCreate: String,
roleDelete: String,
roleUpdate: String,
}
}
This saves channel IDs so users can decide where each event will be logged. I have this set up in the schema and all good, but when I do findOneAndUpdate I don't know how to edit a single field; for example, let's say I want to edit roleDelete which is inside channels.logging.role how would I do that? because doing
await doc.updateOne({channels:{logging:{role:{roleDelete: IDHERE}}}});
It does not work. In fact, it screws everything up and replaces everything within channels to the value given, so how would I go around actually updating ONE value without messing with everything else? Thank you so much for your attention and participation.
This is using NodeJS Mongoose NPM Package btw.
you need to use $set operator. you can find details on https://docs.mongodb.com/manual/reference/operator/update/set/index.html
doc.updateOne({ _id: ID }, {
$set: {
channels.logging.role.roleDelete: IDHERE
}
}
So I solved this by doing the following:
await doc.updateOne({ 'channels.logging.role.roleDelete': IDHERE}, { new: true, upsert: true, setDefaultsOnInsert: true });
This updated the value if it existed and created it if it didn't exist. Using the above methods uses $set internally. (Read more here)
Feel free to ask if I didn't make myself clear
How can I get one document only by query in RethinkDB?
for an example, I want to get the document by this query below:
let searchQuery = {
name: 'rob'
}
var cursor = await r.table('users').filter(searchQuery).run(connection)
var user = await cursor.toArray()
console.log(user)
Result:
[ { email: 'fooz#bar.com',
id: '00e18124-714b-4298-aa34-5126ebda8828',
name: 'rob' } ]
Filter method actually returns a list of users with the same name - 'rob'.
I want the result like get method:
r.table('posts').get('a9849eef-7176-4411-935b-79a6e3c56a74').run(conn, callback);
Result:
{ email: 'fooz#bar.com',
id: '00e18124-714b-4298-aa34-5126ebda8828',
name: 'rob' }
But this method only takes document id.
Any ideas?
get (by id) fetches a single row selection by design, but filter is a streaming operation that processes multiple values (like arrays and streams). You might want to use nth that's designed to query for a stream/array element by its position, or its close alternative (). Here is an example:
.filter({ name: 'rob' })`
will return an array like
[{"email":"fooz#bar.com","id":"230de013-5d6a-436e-a7e9-a891c01913e5","name":"rob"}]
But the following queries
.filter({ name: 'rob' }).nth(0)
.filter({ name: 'rob' })(0)
will both return
{"email":"fooz#bar.com","id":"230de013-5d6a-436e-a7e9-a891c01913e5","name":"rob"}
Note that both also throw ReqlNonExistenceError: Index out of bounds: 0 in case if there are no rows found. However, you can easily fix it using the default operator:
.filter({ name: 'not-rob' }).nth(0).default(null)
Tested using RethinkDB data explorer with the "Raw view" tab active since both "Tree view" and "Table view" display single-element array as a single object. I'm almost sure the RethinkDB query engine is smart enough to make using nth(0) much more efficient rather than fetching the whole cursor to an array and taking the latter's first element in your code.
I can't figure out what I'm doing wrong with my query. I want to get the number of "alertes" with the field "resolved: false" so my query is :
Alertes.find({resolved: false}).count();
But it returns me 0 despite I have 1 entry in the collection with the field resolved: false
Somone could help me to figure out what I'm doing wrong ?
I had forgot to subscribe to the collection in my IronRouter file :
Router.route('/', {
name: 'home',
waitOn: function() {
return [
Meteor.subscribe('infosContainers'),
Meteor.subscribe('infosMachines'),
Meteor.subscribe('alertes'),
];
},
fastRender: true,
});
Thank you for the help
Did you try this?
Alertes.find({resolved: false}).fecth().length
If you are running this code at the client side, make sure you have subscribed to this collection, and that you have documents that satisfy the filter you are looking for.
Try to query all documents (with no filter) to make sure the documents are there with the query above, and check what you get back:
Alertes.find().fecth()
If you don't find any documents with the resolved property set to false, then the query is returning correctly, and the problem is your subscription.
I'm using $pull to pull a subdocument within an array of a document.
Don't know if it matters but in my case the subdocuments contain _id so they are indexed.
Here are JSONs that describes the schemas:
user: {
_id: String,
items: [UserItem]
}
UserItem: {
_id: String,
score: Number
}
Now my problem is this: I am using $pull to remove certain UserItem's from a User.
var delta = {$pull:{}};
delta.$pull.items={};
delta.$pull.items._id = {$in: ["mongoID1", "mongoID2" ...]};
User.findOneAndUpdate(query, delta, {multi: true}, function(err, data){
//whatever...
});
What i get in data here is the User object after the change, when what i wish to get is the items that were removed from the array (satellite data).
Can this be done with one call to the mongo or do I have to do 2 calls: 1 find and 1 $pull?
Thanks for the help.
You really cannot do this, or at least there is nothing that is going to return the "actual" elements that were "pulled" from the array in any response, even with the newer WriteResponse objects available to the newer Bulk Operations API ( which is kind of the way forward ).
The only way you can really do this is by "knowing" the elements you are "intending" to "pull", and then comparing that to the "original" state of the document before it was modified. The basic MongoDB .findAndModify() method allows this, as do the mongoose wrappers of .findByIdAndUpdate() as well and .findOneAndUpdate().
Basic usage premise:
var removing = [ "MongoId1", "MongoId2" ];
Model.findOneAndUpdate(
query,
{ "$pull": { "items._id": { "$in": removing } } },
{ "new": false },
function(err,doc) {
var removed = doc.items.filter(function(item) {
return removing.indexOf(item) != -1;
});
if ( removed.length > 0 )
console.log(removed);
}
);
Or something along those lines. You basically "turn around" the default mongoose .findOneAndUpdate() ( same for the other methods ) behavior and ask for the "original" document before it was modified. If the elements you asked to "pull" were present in the array then you report them, or inspect / return true or whatever.
So the mongoose methods differ from the reference implementation by returning the "new" document by default. Turn this off, and then you can "compare".
Further notes: "multi" is not a valid option here. The method modifies "one" document by definition. Also you make a statement that the array sub-documents conatain an _id. This is done by "mongoose" by default. But those _id values in the array are "not indexed" unless you specifically define an index on that field. The only default index is the "primary document" _id.