MongoDB搜索嵌入式数组

时间:2013-12-24 17:01:04

标签: java mongodb find

我正在尝试将所有编写的java文件存储在MongoDB中,到目前为止,我已经应用了这样的模式(不完整的条目):

{
"_id" : ObjectId("52b861c230044fd08d6c27c4"),
"interfaces" : [
    {
        "methodInterfaces" : [
            {
                "name" : "add",
                "name_lc" : "add",
                "returnType" : "Integer",
                "returnType_lc" : "integer",
                "parameterTypes" : [
                    "Integer",
                    "Integer"
                ],
                "parameterTypes_lc" : [
                    "integer",
                    "integer"
                ]
            },
            {
                "name" : "isValid",
                "name_lc" : "isvalid",
                "returnType" : "Boolean",
                "returnType_lc" : "boolean",
                "parameterTypes" : [
                    "Integer",
                    "Double"
                ],
                "parameterTypes_lc" : [
                    "integer",
                    "double"
                ]
            }
        ],
        "name" : "Calculator",
        "name_lc" : "calculator",
        "filename" : "Calculator.java",
        "filename_lc" : "calculator.java"
    }
],
"name" : "Calculator",
"name_lc" : "calculator",
"filename" : "Calculator",
"filename_lc" : "calculator",
"path" : "/xyz/Calculator.java",
"md5" : "6dec7e62c5e4f9060c7612c252cd741",
"lastModification" : ""

}

到目前为止,我能够查询包含方法名称的类,但是我无法查询具有特定名称的类(让interfaces.name_lc =“calculator”)必须包含两个具有特定名称的方法(比如说“add”和“divide”),它们本身应该有两个整数,分别为。一个整数和一个double作为参数,并且都返回一个整数(不要怀疑这是否合理 - 只是为了说明目的)。

这只是一个例子;当然,它可能会更复杂。

我不知道如何使用方法和指定的参数查询特定的类。我需要将其描述得清晰,并希望获得清晰的结果。

我无法构建一个返回Calculator ( add(integer,integer):integer; divide(integer,double):integer; )等文件的查询。我得到了,例如,OtherClass ( add():void; method(integer):integer; ),这不是我想要的。我正在尝试这几天,也许有人可以启发我,如何在MongoDB中解决这个问题。非常感谢提前!

1 个答案:

答案 0 :(得分:0)

我不确定您是否能够使用您的文档结构在MongoDB中执行此操作。我遇到的问题是参数 - 我假设你关心参数的顺序(即doSomething(String, int)doSomething(int, String)不一样),查询运算符检查所有值在数组中将数组视为一个集合,因此a)顺序不可知,b)消除重复(所以doSomething(String, String)匹配doSomething(String))(这是因为我使用了$ all关键字,{{3} },特别是底部的注释。

然而,我设法获得了您想要的大部分查询,这可能会指向您正确的方向。

{ "$and" : [ //putting these in an "and" query means all parts have to match
    { "interfaces.methodInterfaces" : 
        { "$elemMatch" : { "name" : "add"}}           //this bit finds documents where the method name is "add"
    } ,
    { "interfaces.methodInterfaces" : 
        { "$elemMatch" : { "returnType" : "Integer"}} // This bit matches the return type
    } , 
    { "interfaces.methodInterfaces.parameterTypes" : 
        { "$all" : [ "Integer" , "Integer"]}          //This *should* find you all documents where the parameter types matches this array. But it doesn't, as it treats it as a set
    }
]}

如果您通过Java驱动程序查询,则如下所示:

BasicDBObject findMethodByName = new BasicDBObject("interfaces.methodInterfaces",
                                     new BasicDBObject("$elemMatch", new BasicDBObject("name", "add")));
BasicDBObject findMethodByReturn = new BasicDBObject("interfaces.methodInterfaces",
                                       new BasicDBObject("$elemMatch", new BasicDBObject("returnType", "Integer")));
BasicDBObject findMethodByParams = new BasicDBObject("interfaces.methodInterfaces.parameterTypes",
                                       new BasicDBObject("$all", asList("Integer", "Integer")));
BasicDBObject query = new BasicDBObject("$and", asList(findMethodByName, findMethodByReturn, findMethodByParams));
DBCursor found = collection.find(query);

我没有包含匹配的类名,因为这似乎不是一个棘手的部分 - 只需构建另一个简单的查询,将其添加到“$和”中。

由于存储参数类型的数组没有给出你想要的东西,我建议你考虑一些更结构化的东西,虽然它有点笨拙。而不是

"parameterTypes" : [
    "Integer",
    "Integer"
]

考虑类似

的内容
"parameterTypes" : {
    "param1" : "Integer",
    "param2" : "Integer"
}

然后你不会进行设置操作,你可以单独查询每个参数。这意味着您也可以按照正确的顺序获得它们。