I have a mongoose schema model that have a field name tags , and it is an array of strings to store some tags in it for each document. I want something for example if I have an array of tags like ["test", "testimonials", "test Doc"] tags in it, when i search for test, it returns all documents with tags that they are testimonials or test doc , it should be work for example like wildcards (test*) .... can anyone help ?
this is the model
tags: {
type: [
{
type: String,
},
],
},
First of all, I'd tweak the Schema if possible. Your schema could be changed to this:
tags: [String]
This also just means an array of strings. You don't need to always need to use/specify the type key unless you're planning to add more fields to the tag schema, but it doesn't look like it from the question.
You can do the following to select all documents with a specific tag. Since I don't know what the name of your model is, I'll just call it "Model".
await Model.find({ tags: "tagName" })
OR
await Model.find({ tags: { $elemMatch: { someKey: someValue } } })
The later is only if you have other mongodb documents inside the array. Since you only have strings in the array, use the first method.
Related
I'm really new to firebase and to be honest I find queries hard to write. I'm working on a script in python using firebase_admin and i'd like the query/answer to be in python code, but in any other programming language is fine.
Here's my one of my document, one document contains photos set
photos: {
id1: true
id2: true
}
I want to be ale to retrieve all items where they have id1 in photos object, what would be the query for that?
As the Firebase documentation on simple queries shows:
# Create a reference to the photos collection
ref = db.collection('documents')
# Create a query against the collection
query_ref = ref.where(u'photos.id1', u'==', True)
For the . notation, see the documentation on fields in nested objects.
Note that you'll probably want to change your data model to use an array for this data, as arrays can now be used to model mathematical sets. With a an array like this in your document:
user: ['id1', 'id2']
You can then filter with:
photos_ref = db.collection('documents')
query = photos_ref.where(u'photos', u'array_contains', u'id1')
To add/remove items to this array-that-behaves-like-a-set, see the documentation on updating elements in an array.
Based on Frank van Puffelen's solution, I was also able to use the dot notation to achieve the nested effect. Querying for objects where the assignment contains the current user's ID.
objectModel: {
objectName: 'foo',
otherField: 'bar',
assignment: {
installerIds: ['1', '2', '3'],
otherfields: 'foobar'
},
}
I was able to query like this
p = { field: 'assignment.installerIds', operator: 'array-contains', value: this.currentInstallerId}
query = query.where(p.field, p.operator, p.value);
or in a more general format like Frank showed:
query_ref = ref.where('assignment.installerIds', 'array-contains', '2');
I have a collection where each document has a field which is an array and contains objects where each object is like {key: 0, value: "Some Value"}. Is there an option to do a comparison like array-contains, except while ignoring the key attribute? like finding all Documents with Arrays that contain an Object whose Value attribute equals to some value?
Thanks
The array-contains operation searches for an exact, complete match. It cannot check on just a subset of the information in the array.
The common workaround is to change your data model to allow the use-case, here by adding another array that contains just the information you have available. For example, if you have an array with some profile information for each user, but also want to be able to query for just their username, you'd end up with two array fields:
users: [
{ name: "AstroPrussia", url: "https://stackoverflow.com/users/5460401" },
{ name: "puf", url: "https://stackoverflow.com/users/209103" }
],
usernames: [
"AstroPrussia",
"puf"
]
Now if you want to search on the entire profile, you'd perform then array-contains on the users field. But if you only have the user's name, you'd perform an array-contains on the usernames field.
I have an objectId like this:
["56153e4c2040efa61b4e267f","56033932efefe0d8657bbd9e"]
To save that information in my model I use:
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Items'
}]
What I'm trying to do is to pull an element of the array that is equal to objectId that I send from the front end in a delete request.
The code I'm using:
_.remove(unit.items, request.params.itemId);
I'm using lodash library.
The problem I suppose is that the array have ObjectId elements and I'm trying to compare with an string that is the request.params.itemId.
I have a very similar setup with an "Event" object that has an array of "Assignment" objects saved as an array of ObjectIds. I was able to simply use
obj.arrayField.remove(idToRemove);
Here is the relevant code inside of my delete route handler:
var id = req.assignment._id;
req.event.assignments.remove(id);
req.event.save(function(err, event) {
//etc
}
Does this work for you?
unit.items.remove(request.params.itemId);
You need to pass the string into mongoose.Types.ObjectId('') to get an actual object you can compare against.
So _.remove(unit.items, mongoose.Types.ObjectId(req.params.itemId));
I have the following model:
var PersonSchema = new Schema({
name: String,
groups: [
{type: Schema.Types.ObjectId, ref: 'Group'}
],
});
I am looking for a query that retrieves all the Persons that are not part of a certain Group (i.e the persons' group array doesn't contain the id of the specified group).
I was thinking about something like this, but I'm not sure it is correct:
Person.find({groups: {$nin: [group._id]})
Nothing wrong with what you are basically attempting, but perhaps the only clarification here is the common misconception that you need operators like $nin or $in when querying an array.
Also you really need to do here is a basic inequality match with $ne:
Person.find({ "groups": { "$ne": group._id } })
The "array" operators are not for "array targets" but for providing a "list" of conditions to test in a convenient form.
Person.find({ "groups": { "$nin": [oneId, twoId,threeId] } })
So just use normal operators for single conditions, and save $in and $nin for where you want to test more than one condition against either a single value or a list. So it's just the other way around.
If you do need to pass a "list" of arguments where "none" of those in the provided list match the contents of the array then you reverse the logic with the $not operator and the $all operator:
Person.find({ "groups": { "$not": { "$all": [oneId,twoId,threeId] } } })
So that means that "none of the list" provided are present in the array.
This is a better way to do this in Mongoose v5.11:
Person.find({ occupation: /host/ }).where('groups').nin(['group1', 'group2']);
The code becomes clearer and has more readability.
I am attempting to insert items at a specific index in an array that may or may not be empty. For example, say I have the following document in my mongoDb collection:
{
title: "abe",
questions: []
}
I would like to do something like set the 5th element in the array to a specific value. I was playing with the mongo db command line and I was able to do the following:
> mytest = []
[ ]
> mytest[4] = 'test'
test
> mytest
[ undefined, undefined, undefined, undefined, "test" ]
Which is basically what I want, but when I attempt to do this from my node.js code I am getting weird results (weird as in, items are not in the correct index). Code below:
Mongoose Schema Definition:
mongoose = require("mongoose")
Schema = mongoose.Schema
surveySchema = new Schema
title: String
questions: [
type: Schema.Types.ObjectId
ref: 'Question'
]
Code doing the update:
surveys.update {id: doc.survey_id},
{
$push: {
questions: {
$each: [doc._id],
$position: doc.sort_order
}
}
},
{upsert:false, multi:true},
callback
The code above is being executed in an asynchronous loop, so it's possible the last item will be inserted before the first item and so on.
Can anyone see any reason why items would not be getting inserted at the correct index? Why does my basic example work but the code does not? Could it have to do with the fact that my schema defines questions as an array of ObjectIds?
Documentation for MongoDB $position:
If the number is greater or equal to the length of the array, the $position modifier has no effect and the operator adds elements to the end of the array.