1
votes

I am trying to run an update subquery style with a not in clase on MongoDB but its not working. I believe its because the toArray casts the ObjectIds to text instead of leaving it as a DBRef. Below is my code:

var items = db.listsProducts.find({_id: {$exists: true}}, {product: true, _id: false}).toArray();
db.products.update({_id: {$nin: items}}, {$set: {'status':'inactive'}},{multi:true});

'product' is the DBRef field in the listProducts collection. 'products' is the collection I'm trying to update.

Instead of updating fields that are not in 'items', it updates all documents.

What am I doing wrong? Thanks.

listsProducts:

{
"_id" : ObjectId("54e4bf7bade0276f008b4567"),
"__type" : "Core\Libs\Listing\Entity\Product",
"type" : "inventoryItem",
"product" : DBRef("products", ObjectId("54e308e23b8e778d128b4799")),
"list" : DBRef("lists", ObjectId("54e4aeab5252416c008b4569")),
"inventoryData" : {
"__type" : "Core\Libs\Listing\Entity\Product\InventoryData",
"parLevel" : NumberLong(0),
"itemsOnHand" : NumberLong(0)
},
"timeLog" : {
"__type" : "Core\Utils\Entity\TimeLog",
"createdAt" : ISODate("2015-02-18T16:36:11.387+0000"),
"updatedAt" : ISODate("2015-07-07T07:31:25.900+0000"),
"deletedAt" : null
}
}

products:

{
"_id" : ObjectId("54e308d83b8e778d128b4588"),
"__type" : "Core\Libs\Product\Entity\Product",
"name" : "Carrot Slices",
"gtin" : "10071179184300",
"status" : "active",
"defaultPrice" : NumberLong(0),
"references" : {
"__type" : "Core\Libs\Product\Entity\Product\References",
"manufacturer" : DBRef("manufacturers", ObjectId("54e308d73b8e778d128b4569")),
"category" : DBRef("1ws-categories", ObjectId("53e1e8723b8e77a52b8b45fd"))
},
"information" : {
"__type" : "Core\Libs\Product\Entity\Product\Information",
"description" : {
"__type" : "Core\Libs\Product\Entity\Product\Description",
"short" : "Carrot Smooth Sli 1/20#",
"long" : "Simplot Classic - Carrot Smooth Sli 1/20#"
},
"attributes" : {
"__type" : "Xeeo\Services\Core\Abstracts\Collection",
"entities" : [
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Brand Name",
"value" : "Simplot Classic"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Manufacturer GLN",
"value" : "0071179000009"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Manufacturer Name",
"value" : "J. R. Simplot Company"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Country Of Origin",
"value" : "US"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Last Modified Date",
"value" : "2014-12-03T09:42:04"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Publication Date",
"value" : "2011-10-26T00:00:00"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Start Availability Date",
"value" : "2014-12-03T00:00:00"
},
{
"__type" : "Core\Utils\Entities\KeyValuePair",
"key" : "Depth (IN)",
"value" : "13.375"
}
]
}
},
"images" : "http://www.fsenetportal.com/FSENetimages.nsf/0/BB29958620D9515A87257AA6005068B1/$file/10071179184300_A1CD.jpg?OpenElement",
"elasticSearchIndexStatus" : "indexed",
"timeLog" : {
"__type" : "Core\Utils\Entity\TimeLog",
"createdAt" : ISODate("2015-02-17T09:24:40.138+0000"),
"updatedAt" : ISODate("2016-03-25T00:56:21.219+0000"),
"deletedAt" : null
}
}

1

1 Answers

2
votes

{_id: {$nin: items}} expects an array of ObjectIds and from what I can see you're passing an array of documents and what's even worse you seem to be telling mongo not to select _id in your findquery.

This is how I would go about this.

var items = db.listsProducts.find({_id: {$exists: true}}, {product: true, _id: true}).toArray();

var itemIds = items.map(function(i) {
    return i._id;
});

db.products.update({_id: {$nin: itemIds}}, {$set: {status: 'inactive'}}, {multi: true});