MongoDB按特定属性列表中的条目进行排序

huangapple go评论104阅读模式
英文:

Mongo SORT with specific entry from list of attribute

问题

我正在使用Java处理Mongo聚合/筛选/排序和限制。

我有以下模型对象。CustomPOJO 是我的数据库集合。

@Document(collection = "CustomPOJO")
public class CustomPOJO {

    public List<KeyValueObject> valueList;
    public String attribute1;
    public String attribute2;
    public CustomObject attribute3;

}

public class CustomObject {
    public String attribute4;
    public String attribute5;
}

public class KeyValueObject {
    public String name;
    public String value;
}

现在我在我的数据库中有以下记录条目:

记录1:

{
    "valueList": [{
        "name": "field1",
        "value": "value1"
    }, {
        "name": "field2",
        "value": "value2"
    }, {
        "name": "field3",
        "value": "value3"
    }],
    "attribute1": "attribute1",
    "attribute2": "attribute2",
    "attribute3": {
        "attribute4": "attribute4",
        "attribute5": "attribute5"
    }

}

记录2:

{
    "valueList": [{
        "name": "field1",
        "value": "value4"
    }, {
        "name": "field2",
        "value": "value5"
    }, {
        "name": "field3",
        "value": "value6"
    }],
    "attribute1": "attribute11",
    "attribute2": "attribute22",
    "attribute3": {
        "attribute4": "attribute44",
        "attribute5": "attribute55"
    }

}

我可以使用 sort(DESC, "attribute1")sort(DESC, "attribute3.attribute4")sort(DESC, "attribute2") 在所有字段上进行排序。但是我无法对 valueList 进行排序。我希望根据 valueList 内的特定 KeyValue 条目进行排序。

例如,记录1的 valueList 包含条目 field1,所以数据库中的所有记录应该根据其中的 field1 和其内部的 value 进行排序。

总之,我想要在列表属性内部的字段上进行排序。

非常感谢您的帮助。

英文:

I am working with Mongo aggregation/filter/sorting and limit with JAVA.

I have below model objects. CustomPOJO is my database collection.

@Document(collation = &quot;CustomPOJO&quot;)
public class CustomPOJO {

    public List&lt;KeyValueObject&gt; valueList;
    public String attribute1;
    public String attribute2;
    public CustomObject attribute3;

}

public class CustomObject {
    public String attribute4;
    public String attribute5;
}

public class KeyValueObject {
    public String name;
    public String value;
}

Now I have entries in my DB with below records

Record1:

{
	&quot;valueList&quot;: [{
		&quot;name&quot;: &quot;field1&quot;,
		&quot;value&quot;: &quot;value1&quot;
	}, {
		&quot;name&quot;: &quot;field2&quot;,
		&quot;value&quot;: &quot;value2&quot;
	}, {
		&quot;name&quot;: &quot;field3&quot;,
		&quot;value&quot;: &quot;value3&quot;
	}],
	&quot;attribute1&quot;: &quot;attribute1&quot;,
	&quot;attribute2&quot;: &quot;attribute2&quot;,
	&quot;attribute3&quot;: {
		&quot;attribute4&quot;: &quot;attribute4&quot;,
		&quot;attribute5&quot;: &quot;attribute5&quot;
	}

}

Record2:

{
	&quot;valueList&quot;: [{
		&quot;name&quot;: &quot;field1&quot;,
		&quot;value&quot;: &quot;value4&quot;
	}, {
		&quot;name&quot;: &quot;field2&quot;,
		&quot;value&quot;: &quot;value5&quot;
	}, {
		&quot;name&quot;: &quot;field3&quot;,
		&quot;value&quot;: &quot;value6&quot;
	}],
	&quot;attribute1&quot;: &quot;attribute11&quot;,
	&quot;attribute2&quot;: &quot;attribute22&quot;,
	&quot;attribute3&quot;: {
		&quot;attribute4&quot;: &quot;attribute44&quot;,
		&quot;attribute5&quot;: &quot;attribute55&quot;
	}

}

I am able to do sort on all fields using sort(DESC,&quot;attribute1&quot;) or sort(DESC,&quot;attribute3.attribute4&quot;) or sort(DESC,&quot;attribute2&quot;). But i am unable to sort on valueList. I want to do sort according to specific KeyValue entry inside of valueList.

For example record1 have valueList with entry field1 so all records in DB should sort according field1 and value inside it.

In general i want to sort on field inside of list attribute.

Any help will be highly appreciate.

答案1

得分: 1

无法在原地使用数组的键值对进行排序。您可以使用聚合框架来实现。

将与键匹配的条目投影出来,然后按值进行排序,并从文档中移除额外的字段。

类似这样:

db.collection.aggregate(
  [
    {
      "$set": {
        "sortdoc": {
          "$arrayElemAt": [
            {
              "$filter": {
                "input": "$valueList",
                "cond": { "$eq": ["$$this.name", "field1"] }
              }
            },
            0
          ]
        }
      }
    },
    { "$sort": { "sortdoc.value": -1 } },
    { "$project": { "sortdoc": 0 } }
  ]
)

您还可以将valueList建模为对象,就像您为属性做的那样。使用Document类或HashMap代替值的列表,并使用sort(DESC, "document.field1")

@Document(collation = "CustomPOJO")
public class CustomPOJO {

  public Document document;
  public String attribute1;
  public String attribute2;
  public CustomObject attribute3;

}

文档:

{
  "document": {
    "field1": "value1",
    "field2": "value2"
  },
  "attribute1": "attribute1",
  "attribute2": "attribute2",
  "attribute3": {
    "attribute4": "attribute4",
    "attribute5": "attribute5"
  }
}
英文:

You can't sort using array's key value pair in place. You could use aggregation framework.

Project the document matching key entry followed by sort on the value and remove the additional field from the document.

Something like

db.collection.aggregate(
[
  {&quot;$set&quot;:{
    &quot;sortdoc&quot;:{
      &quot;$arrayElemAt&quot;:[
        {
          &quot;$filter&quot;:{
            &quot;input&quot;:&quot;$valueList&quot;,
            &quot;cond&quot;:{&quot;$eq&quot;:[&quot;$$this.name&quot;,&quot;field1&quot;]}
          }
        },0]}
  }},
  {&quot;$sort&quot;:{&quot;sortdoc.value&quot;:-1}},
  {&quot;$project&quot;:{&quot;sortdoc&quot;:0}}
])

https://mongoplayground.net/p/gzLQm8m2wQW

You could also model valueList as object just the way you have for attributes. Use Document class or HashMap instead of List of values and use sort(DESC,&quot;document.field1&quot;)

@Document(collation = &quot;CustomPOJO&quot;)
public class CustomPOJO {

  public Document document;
  public String attribute1;
  public String attribute2;
  public CustomObject attribute3;

}

Document

{
    &quot;document&quot;: {
      &quot;field1&quot;: &quot;value1&quot;,
      &quot;field2&quot;: &quot;value2&quot;
    },
    &quot;attribute1&quot;: &quot;attribute1&quot;,
    &quot;attribute2&quot;: &quot;attribute2&quot;,
    &quot;attribute3&quot;: {
      &quot;attribute4&quot;: &quot;attribute4&quot;,
      &quot;attribute5&quot;: &quot;attribute5&quot;
    }
}

答案2

得分: 0

你无法直接对数组内部字段进行排序。通常我会使用 unwind 操作对数组展开,然后进行排序。

也许这对你有所帮助。

db.collection.aggregate([
  {
    "$unwind": "$valueList"
  },
  {
    "$sort": {
      "valueList.name": -1
    }
  }
])

Mongo Playground

英文:

You cannot sort documents on fields inside of Arrays directly. Generally what i do is unwind the array and then perform sort.

May be this is something that may help you.

db.collection.aggregate([
  {
    &quot;$unwind&quot;: &quot;$valueList&quot;
  },
  {
    &quot;$sort&quot;: {
      &quot;valueList.name&quot;: -1
    }
  }
])

Mongo Playground

huangapple
  • 本文由 发表于 2020年10月15日 22:06:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/64373360.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定