Reputation: 6002
Suppose you have this array of fileNames
:
[
'filename1_c4d.rar',
'text122_octane.c4d',
'texture1.png',
'texture2.png',
]
And in my database I have a collection of Tags
:
[
{
_id: 'id1',
name: 'cinema4d',
aliases: ['.c4d', 'c4d', 'cinema4d'],
},
{
_id: 'id2',
name: 'octane',
aliases: ['octane'],
},
{
_id: 'id3',
name: 'textures',
aliases: ['texture', 'textures'],
},
// ...
]
My goal is to fetch all Tags
that have a substring of my fileNames
in aliases
, with the help of mongoose
. (Tags.find({ someFancyQuery: fileNames })
)
Here is an example to make it better understandable:
I have this fileName: filename1_c4d.rar
. Based on this name the query should be able to fetch the Tag
with the name cinema4d
, because it's aliases include a substring of the fileName filename1_
c4d
.rar
So those fileNames should fetch the following Tags
:
filename1_
c4d
.rar
➔ cinema4d
text122_
octane
.
c4d
➔ cinema4d, octane
texture
1.png
➔ textures
texture
2.png
➔ textures
So in the end the result of the query should be those Tags
(without duplicated):
cinema4d, octane, textures
P.S.: To explain what this is for:
A user can upload e.g. a .rar
file and I want to automatically assign tags based on the filenames, that are inside the .rar
file.
I hope it's clear what my goal is. Please let me know if there is somewthing you don't understand.
Upvotes: 2
Views: 424
Reputation: 12817
you need to use aggregation pipeline to compare alias is substring of input array
db.t5.aggregate([
{$addFields :{tags: tags, matches : {$map:{input: "$aliases", as: "a", in: {$map : {input: tags, as: "i", in: {$gte:[{$indexOfCP:["$$i", "$$a"]},0]}}}}}}},
{$addFields: {matchez :{$reduce : {input : "$matches", initialValue : [], in: { $concatArrays: [ "$$value", "$$this" ] }}}}},
{$match: {"matchez" : {$in : [true]}}},
{$group : {_id: null, names : {$addToSet : "$name"}}}
])
result
{ "_id" : null, "names" : [ "octane", "textures", "cinema4d" ] }
sample collection
> db.t5.find()
{ "_id" : "id1", "name" : "cinema4d", "aliases" : [ ".c4d", "c4d", "cinema4d" ] }
{ "_id" : "id2", "name" : "octane", "aliases" : [ "octane" ] }
{ "_id" : "id3", "name" : "textures", "aliases" : [ "texture", "textures" ] }
{ "_id" : "id4" }
{ "_id" : "id5" }
{ "_id" : "id6" }
input tags
> tags
[
"filename1_c4d.rar",
"text122_octane.c4d",
"texture1.png",
"texture2.png"
]
result
> db.t5.aggregate([{$addFields :{tags: tags, matches : {$map:{input: "$aliases", as: "a", in: {$map : {input: tags, as: "i", in: {$gte:[{$indexOfCP:["$$i", "$$a"]},0]}}}}}}}, {$addFields: {matchez :{$reduce : {input : "$matches", initialValue : [], in: { $concatArrays: [ "$$value", "$$this" ] }}}}}, {$match: {"matchez" : {$in : [true]}}}, {$group : {_id: null, names : {$addToSet : "$name"}}}])
{ "_id" : null, "names" : [ "octane", "textures", "cinema4d" ] }
>
Upvotes: 1