MongoDB的数组查询 - xbwen/xbwen.github.io GitHub Wiki
今天同事来问我一个MongoDB数组查询的问题。问题很简单,但比较有趣,这里记录一下。
假设某数据表中有三条记录,如下:
{
"_id" : ObjectId("5ac9ffb677c8314f2047c80b"),
"title" : "title 1",
"tags" : ["a", "b"]
}
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80c"),
"title" : "title 2",
"tags" : ["a", "b", "c"]
}
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80d"),
"title" : "title 3",
"tags" : ["a", "b", "c", "d"]
}
针对数组tags,如果用$eq查询:
//请注意数组元素的顺序
//第一个查询
List list1 = dao.query().is("tags", new String[]{"a", "b", "c"}).results();
//第二个查询
List list2 = dao.query().is("tags", new String[]{"c", "b", "a"}).results();
上面的第一个查询,返回的是1条记录:
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80c"),
"title" : "title 2",
"tags" : ["a", "b", "c"]
}
上面的第二个查询,结果为空,不返回任何记录。
这是因为,对于$eq查询,是要求严格相等的,包括元素的顺序。所以,在实际项目中,几乎不会用$eq来对数组进行匹配。
MongoDB中提供了专门的数组查询操作,包括:$all, $eleMatch, $size。
其中,$all查询,匹配的是 “包含所有指定元素” 的记录,而不管元素的顺序。例如:
List list = dao.query().all("tags", new String[]{"c", "b", "a"}).results();
返回的是2条记录:
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80c"),
"title" : "title 2",
"tags" : ["a", "b", "c"]
}
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80d"),
"title" : "title 3",
"tags" : ["a", "b", "c", "d"]
}
同事的问题是:如何匹配 “包含,且只包含,所有指定元素” 的记录呢?拿上面的例子来说,就是只匹配["a", "b", "c"]这条记录。
答案很简单,就是结合$all和$size一起查询:
List list = dao.query().all("tags", new String[]{"c", "b", "a"}).size("tags", 3).results();
返回的结果就是1条记录:
{
"_id" : ObjectId("5ac9ffb777c8314f2047c80c"),
"title" : "title 2",
"tags" : ["a", "b", "c"]
}