Mongodb 在Mongo中存储查询

Mongodb 在Mongo中存储查询,mongodb,Mongodb,这种情况是这样的:我想在一个webshop中根据一组参数配置哪些项目应该列在sjop中。 我希望这是可配置的,因为这允许我实验不同的参数,也可以轻松地更改它们的值 我有一个要基于多个参数查询的产品集合。 以下是其中的几个: 在产品中: "delivery" : { "maximum_delivery_days" : 30, "average_delivery_days" : 10, "source" : 1, "filling_rate" : 85, "s

这种情况是这样的:我想在一个webshop中根据一组参数配置哪些项目应该列在sjop中。 我希望这是可配置的,因为这允许我实验不同的参数,也可以轻松地更改它们的值

我有一个要基于多个参数查询的产品集合。 以下是其中的几个:

在产品中:

"delivery" : {
    "maximum_delivery_days" : 30,
    "average_delivery_days" : 10,
    "source" : 1,
    "filling_rate" : 85,
    "stock" : 0
}
但也存在其他参数

决定是否包含产品的此类查询的一个示例可以是:

"$or" : [
        {
            "delivery.stock" : 1
        },
        {
            "$or" : [
                    {
                            "$and" : [
                                    {
                                            "delivery.maximum_delivery_days" : {
                                                    "$lt" : 60
                                            }
                                    },
                                    {
                                            "delivery.filling_rate" : {
                                                    "$gt" : 90
                                            }
                                    }
                            ]
                    },
                    {
                            "$and" : [
                                    {
                                            "delivery.maximum_delivery_days" : {
                                                    "$lt" : 40
                                            }
                                    },
                                    {
                                            "delivery.filling_rate" : {
                                                    "$gt" : 80
                                            }
                                    }
                            ]
                    },
                    {
                            "$and" : [
                                    {
                                            "delivery.delivery_days" : {
                                                    "$lt" : 25
                                            }
                                    },
                                    {
                                            "delivery.filling_rate" : {
                                                    "$gt" : 70
                                            }
                                    }
                            ]
                    }
            ]
        }
]
现在要使其可配置,我需要能够处理布尔逻辑、参数和值。 因此,我有了这样的想法,因为这样的查询本身就是JSON,将其存储在Mongo中,并让我的Java应用程序检索它。 下一件事是在过滤器中使用它(例如find或其他),并对相应的产品进行选择。 这种方法的优点是,我可以在程序之外实际分析数据和查询的有效性

我会将它按名称存储在数据库中。例如

{ 
    "name": "query1",
    "query": { the thing printed above starting with "$or"... }
}
使用:

db.queries.insert({
    "name" : "query1",
    "query": { the thing printed above starting with "$or"... }
})
其结果是:

2016-03-27T14:43:37.265+0200 E QUERY    Error: field names cannot start with $ [$or]
    at Error (<anonymous>)
    at DBCollection._validateForStorage (src/mongo/shell/collection.js:161:19)
    at DBCollection._validateForStorage (src/mongo/shell/collection.js:165:18)
    at insert (src/mongo/shell/bulk_api.js:646:20)
    at DBCollection.insert (src/mongo/shell/collection.js:243:18)
    at (shell):1:12 at src/mongo/shell/collection.js:161
这样做的结果是:

WriteResult({
        "nMatched" : 0,
        "nUpserted" : 0,
        "nModified" : 0,
        "writeError" : {
                "code" : 52,
                "errmsg" : "The dollar ($) prefixed field '$or' in 'action.$or' is not valid for storage."
        }
})
似乎与上面的另一条信息非常接近


我要说的是,我对这里发生的事情一无所知,所以我希望这里的一些wizzard能够对这件事有所帮助

我认为错误消息包含了您需要考虑的重要信息:

查询错误:字段名不能以开头$

由于您试图在文档中存储查询(或查询的一部分),因此最终会得到包含mongo运算符关键字的属性名称(例如
$或
$ne
$gt
)重点补充

字段名不能包含点(即…)或空字符,它们不能以美元符号(即$)开头。


在这些情况下,我不会信任第三方应用程序,如Robomongo。我建议直接在mongo shell中调试/测试此问题


我的建议是在文档中存储查询的转义版本,以免干扰保留的运算符关键字。您可以使用可用的
JSON.stringify(my_obj)
将部分查询编码为字符串,然后在以后选择检索时对其进行解析/解码:
JSON.parse(从\u db中转义\u query\u string\u)
在MongoDB中将查询存储为JSON对象的方法是不可行的

您可能会将查询逻辑和字段存储在MongoDB中,但您必须让外部应用程序使用正确的MongoDB语法构建查询

MongoDB查询包含运算符,其中一些具有特殊字符

mongoDB文件名有一些规则。这些规则不允许使用特殊字符。 看这里:

有时使用Robomongo成功创建文档的可能原因是,Robomongo正在将查询转换为字符串,并在将其发送到MongoDB时正确转义特殊字符


这也解释了为什么更新它们的尝试永远不起作用。您试图创建一个文档,但却创建了一个字符串对象,因此您的更新条件可能无法检索任何文档。

我发现您的方法存在两个问题

在下面的查询中

db.queries.insert({
   "name" : "query1",
   "query": { the thing printed above starting with "$or"... }
})
有效的JSON需要密钥、值对。在这里的
“查询”
中,您正在存储一个没有
键的对象。你有两个选择。将查询存储为文本或在大括号内创建另一个键

第二个问题是,您正在存储
query
值,而不使用引号括起来。所有字符串值必须用引号括起来

因此,您的最终文档应显示为

db.queries.insert({
    "name" : "query1",
    "query": 'the thing printed above starting with "$or"... '
})

现在试试看,它应该会起作用。

显然,我试图用mongo的方式存储查询是愚蠢的,@bigdatakid和@lix的答案都清楚地表明了这一点。所以我最后做的是:我修改了字段的命名,以符合mongo的要求

例如,代替$或我使用了$或等,而不是使用a。在名字里面我用了一个#。我正在Java代码中替换这两个

通过这种方式,我仍然可以在程序之外轻松地尝试和测试查询。在我的Java程序中,我只是更改名称并使用查询。仅使用两行代码。它现在就可以工作了。谢谢你们的建议

String documentAsString = query.toJson().replaceAll("_\\$", "\\$").replaceAll("#", ".");
    Object q = JSON.parse(documentAsString);

所以您是否建议将字符串化对象存储为字符串而不是对象本身?您还写道:“我建议直接在mongo shell中调试/测试这个问题。”如何?最后,(提供更多信息)使用Robomongo存储的对象可以作为普通对象使用,检索后可以通过我的Java程序传递给查询。所以,这些确实有效。是的-我建议您以转义格式(字符串化)存储数据。这将防止
$
字符干扰mongo关键字。关于我所说的调试/测试,我的意思是,您应该在命令行内测试此方法是否确实适用于您的案例,而不是通过第三方接口(Robomongo)。我仍然对该方法感到好奇。我应该使用Javascript来实现这一点吗?可能是的。顺便说一句,这里是一个屏幕转储的对象被插入使用机器人。根据您的应用程序,您可以使用Javascript来转义字符串…尽管您使用的几乎任何语言都应该有类似的转义/编码字符串的方式,以便它们不会干扰其他功能…我过去在Robomongo以及它处理/解析日期的方式(日期对象与ISODate)方面遇到过问题-如果他们对它接收到的查询字符串进行了某种欺骗,我也不会感到惊讶……我是一名程序员,但对API和Robo的功能感到困惑。因为正如在另一个线程中提到的,存储的对象在我的Java中肯定是可用的,并且可以作为查询参数传入(例如f
String documentAsString = query.toJson().replaceAll("_\\$", "\\$").replaceAll("#", ".");
    Object q = JSON.parse(documentAsString);